Annotation of /trunk/kernel26-magellan/patches-2.6.17-r6/0104-2.6.17.11-all-fixes.patch
Parent Directory | Revision Log
Revision 105 -
(hide annotations)
(download)
Sun Mar 11 16:17:56 2007 UTC (17 years, 6 months ago) by niro
File size: 24372 byte(s)
Sun Mar 11 16:17:56 2007 UTC (17 years, 6 months ago) by niro
File size: 24372 byte(s)
2.6.17-magellan-r6
1 | niro | 105 | diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c |
2 | index c7b943f..3edefc8 100644 | ||
3 | --- a/arch/ia64/kernel/sys_ia64.c | ||
4 | +++ b/arch/ia64/kernel/sys_ia64.c | ||
5 | @@ -164,10 +164,25 @@ sys_pipe (void) | ||
6 | return retval; | ||
7 | } | ||
8 | |||
9 | +int ia64_map_check_rgn(unsigned long addr, unsigned long len, | ||
10 | + unsigned long flags) | ||
11 | +{ | ||
12 | + unsigned long roff; | ||
13 | + | ||
14 | + /* | ||
15 | + * Don't permit mappings into unmapped space, the virtual page table | ||
16 | + * of a region, or across a region boundary. Note: RGN_MAP_LIMIT is | ||
17 | + * equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0. | ||
18 | + */ | ||
19 | + roff = REGION_OFFSET(addr); | ||
20 | + if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) | ||
21 | + return -EINVAL; | ||
22 | + return 0; | ||
23 | +} | ||
24 | + | ||
25 | static inline unsigned long | ||
26 | do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff) | ||
27 | { | ||
28 | - unsigned long roff; | ||
29 | struct file *file = NULL; | ||
30 | |||
31 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
32 | @@ -189,17 +204,6 @@ do_mmap2 (unsigned long addr, unsigned l | ||
33 | goto out; | ||
34 | } | ||
35 | |||
36 | - /* | ||
37 | - * Don't permit mappings into unmapped space, the virtual page table of a region, | ||
38 | - * or across a region boundary. Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE | ||
39 | - * (for some integer n <= 61) and len > 0. | ||
40 | - */ | ||
41 | - roff = REGION_OFFSET(addr); | ||
42 | - if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) { | ||
43 | - addr = -EINVAL; | ||
44 | - goto out; | ||
45 | - } | ||
46 | - | ||
47 | down_write(¤t->mm->mmap_sem); | ||
48 | addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
49 | up_write(¤t->mm->mmap_sem); | ||
50 | diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c | ||
51 | index 0cdfc9d..fc8cdcc 100644 | ||
52 | --- a/arch/sparc/kernel/sys_sparc.c | ||
53 | +++ b/arch/sparc/kernel/sys_sparc.c | ||
54 | @@ -219,6 +219,21 @@ out: | ||
55 | return err; | ||
56 | } | ||
57 | |||
58 | +int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) | ||
59 | +{ | ||
60 | + if (ARCH_SUN4C_SUN4 && | ||
61 | + (len > 0x20000000 || | ||
62 | + ((flags & MAP_FIXED) && | ||
63 | + addr < 0xe0000000 && addr + len > 0x20000000))) | ||
64 | + return -EINVAL; | ||
65 | + | ||
66 | + /* See asm-sparc/uaccess.h */ | ||
67 | + if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) | ||
68 | + return -EINVAL; | ||
69 | + | ||
70 | + return 0; | ||
71 | +} | ||
72 | + | ||
73 | /* Linux version of mmap */ | ||
74 | static unsigned long do_mmap2(unsigned long addr, unsigned long len, | ||
75 | unsigned long prot, unsigned long flags, unsigned long fd, | ||
76 | @@ -233,25 +248,13 @@ static unsigned long do_mmap2(unsigned l | ||
77 | goto out; | ||
78 | } | ||
79 | |||
80 | - retval = -EINVAL; | ||
81 | len = PAGE_ALIGN(len); | ||
82 | - if (ARCH_SUN4C_SUN4 && | ||
83 | - (len > 0x20000000 || | ||
84 | - ((flags & MAP_FIXED) && | ||
85 | - addr < 0xe0000000 && addr + len > 0x20000000))) | ||
86 | - goto out_putf; | ||
87 | - | ||
88 | - /* See asm-sparc/uaccess.h */ | ||
89 | - if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) | ||
90 | - goto out_putf; | ||
91 | - | ||
92 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
93 | |||
94 | down_write(¤t->mm->mmap_sem); | ||
95 | retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
96 | up_write(¤t->mm->mmap_sem); | ||
97 | |||
98 | -out_putf: | ||
99 | if (file) | ||
100 | fput(file); | ||
101 | out: | ||
102 | diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c | ||
103 | index 7a86913..a9edcab 100644 | ||
104 | --- a/arch/sparc64/kernel/sys_sparc.c | ||
105 | +++ b/arch/sparc64/kernel/sys_sparc.c | ||
106 | @@ -549,6 +549,26 @@ asmlinkage long sparc64_personality(unsi | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | +int sparc64_mmap_check(unsigned long addr, unsigned long len, | ||
111 | + unsigned long flags) | ||
112 | +{ | ||
113 | + if (test_thread_flag(TIF_32BIT)) { | ||
114 | + if (len >= STACK_TOP32) | ||
115 | + return -EINVAL; | ||
116 | + | ||
117 | + if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) | ||
118 | + return -EINVAL; | ||
119 | + } else { | ||
120 | + if (len >= VA_EXCLUDE_START) | ||
121 | + return -EINVAL; | ||
122 | + | ||
123 | + if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) | ||
124 | + return -EINVAL; | ||
125 | + } | ||
126 | + | ||
127 | + return 0; | ||
128 | +} | ||
129 | + | ||
130 | /* Linux version of mmap */ | ||
131 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | ||
132 | unsigned long prot, unsigned long flags, unsigned long fd, | ||
133 | @@ -564,27 +584,11 @@ asmlinkage unsigned long sys_mmap(unsign | ||
134 | } | ||
135 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
136 | len = PAGE_ALIGN(len); | ||
137 | - retval = -EINVAL; | ||
138 | - | ||
139 | - if (test_thread_flag(TIF_32BIT)) { | ||
140 | - if (len >= STACK_TOP32) | ||
141 | - goto out_putf; | ||
142 | - | ||
143 | - if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) | ||
144 | - goto out_putf; | ||
145 | - } else { | ||
146 | - if (len >= VA_EXCLUDE_START) | ||
147 | - goto out_putf; | ||
148 | - | ||
149 | - if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) | ||
150 | - goto out_putf; | ||
151 | - } | ||
152 | |||
153 | down_write(¤t->mm->mmap_sem); | ||
154 | retval = do_mmap(file, addr, len, prot, flags, off); | ||
155 | up_write(¤t->mm->mmap_sem); | ||
156 | |||
157 | -out_putf: | ||
158 | if (file) | ||
159 | fput(file); | ||
160 | out: | ||
161 | diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c | ||
162 | index 8ea7062..2678034 100644 | ||
163 | --- a/drivers/char/tpm/tpm_tis.c | ||
164 | +++ b/drivers/char/tpm/tpm_tis.c | ||
165 | @@ -424,6 +424,7 @@ static irqreturn_t tis_int_handler(int i | ||
166 | iowrite32(interrupt, | ||
167 | chip->vendor.iobase + | ||
168 | TPM_INT_STATUS(chip->vendor.locality)); | ||
169 | + ioread32(chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality)); | ||
170 | return IRQ_HANDLED; | ||
171 | } | ||
172 | |||
173 | diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c | ||
174 | index 8f1292c..d1788cd 100644 | ||
175 | --- a/drivers/ieee1394/ohci1394.c | ||
176 | +++ b/drivers/ieee1394/ohci1394.c | ||
177 | @@ -3548,6 +3548,8 @@ #endif /* CONFIG_PPC_PMAC */ | ||
178 | |||
179 | static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) | ||
180 | { | ||
181 | + pci_save_state(pdev); | ||
182 | + | ||
183 | #ifdef CONFIG_PPC_PMAC | ||
184 | if (machine_is(powermac)) { | ||
185 | struct device_node *of_node; | ||
186 | @@ -3559,8 +3561,6 @@ #ifdef CONFIG_PPC_PMAC | ||
187 | } | ||
188 | #endif | ||
189 | |||
190 | - pci_save_state(pdev); | ||
191 | - | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c | ||
196 | index 1816f30..5af5265 100644 | ||
197 | --- a/drivers/md/dm-mpath.c | ||
198 | +++ b/drivers/md/dm-mpath.c | ||
199 | @@ -711,6 +711,8 @@ static int multipath_ctr(struct dm_targe | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | + m->ti = ti; | ||
204 | + | ||
205 | r = parse_features(&as, m, ti); | ||
206 | if (r) | ||
207 | goto bad; | ||
208 | @@ -752,7 +754,6 @@ static int multipath_ctr(struct dm_targe | ||
209 | } | ||
210 | |||
211 | ti->private = m; | ||
212 | - m->ti = ti; | ||
213 | |||
214 | return 0; | ||
215 | |||
216 | diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c | ||
217 | index 4070eff..5a54494 100644 | ||
218 | --- a/drivers/md/raid1.c | ||
219 | +++ b/drivers/md/raid1.c | ||
220 | @@ -1486,7 +1486,6 @@ static void raid1d(mddev_t *mddev) | ||
221 | d = conf->raid_disks; | ||
222 | d--; | ||
223 | rdev = conf->mirrors[d].rdev; | ||
224 | - atomic_add(s, &rdev->corrected_errors); | ||
225 | if (rdev && | ||
226 | test_bit(In_sync, &rdev->flags)) { | ||
227 | if (sync_page_io(rdev->bdev, | ||
228 | @@ -1509,6 +1508,9 @@ static void raid1d(mddev_t *mddev) | ||
229 | s<<9, conf->tmppage, READ) == 0) | ||
230 | /* Well, this device is dead */ | ||
231 | md_error(mddev, rdev); | ||
232 | + else | ||
233 | + atomic_add(s, &rdev->corrected_errors); | ||
234 | + | ||
235 | } | ||
236 | } | ||
237 | } else { | ||
238 | diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c | ||
239 | index a3cd0b3..72ca553 100644 | ||
240 | --- a/drivers/net/sky2.c | ||
241 | +++ b/drivers/net/sky2.c | ||
242 | @@ -233,6 +233,8 @@ static void sky2_set_power_state(struct | ||
243 | if (hw->ports > 1) | ||
244 | reg1 |= PCI_Y2_PHY2_COMA; | ||
245 | } | ||
246 | + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
247 | + udelay(100); | ||
248 | |||
249 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | ||
250 | sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON); | ||
251 | @@ -243,8 +245,6 @@ static void sky2_set_power_state(struct | ||
252 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); | ||
253 | } | ||
254 | |||
255 | - sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
256 | - | ||
257 | break; | ||
258 | |||
259 | case PCI_D3hot: | ||
260 | diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c | ||
261 | index d378478..6e3786f 100644 | ||
262 | --- a/drivers/pci/quirks.c | ||
263 | +++ b/drivers/pci/quirks.c | ||
264 | @@ -427,6 +427,7 @@ static void __devinit quirk_ich6_lpc_acp | ||
265 | pci_read_config_dword(dev, 0x48, ®ion); | ||
266 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); | ||
267 | } | ||
268 | +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); | ||
269 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); | ||
270 | |||
271 | /* | ||
272 | @@ -1043,7 +1044,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I | ||
273 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | ||
274 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | ||
275 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | ||
276 | -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc ); | ||
277 | |||
278 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | ||
279 | { | ||
280 | diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig | ||
281 | index 7d22dc0..753b364 100644 | ||
282 | --- a/drivers/serial/Kconfig | ||
283 | +++ b/drivers/serial/Kconfig | ||
284 | @@ -803,6 +803,7 @@ config SERIAL_MPC52xx | ||
285 | tristate "Freescale MPC52xx family PSC serial support" | ||
286 | depends on PPC_MPC52xx | ||
287 | select SERIAL_CORE | ||
288 | + select FW_LOADER | ||
289 | help | ||
290 | This drivers support the MPC52xx PSC serial ports. If you would | ||
291 | like to use them, you must answer Y or M to this option. Not that | ||
292 | diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c | ||
293 | index 68ebd10..aa50dc6 100644 | ||
294 | --- a/fs/befs/linuxvfs.c | ||
295 | +++ b/fs/befs/linuxvfs.c | ||
296 | @@ -512,7 +512,11 @@ befs_utf2nls(struct super_block *sb, con | ||
297 | wchar_t uni; | ||
298 | int unilen, utflen; | ||
299 | char *result; | ||
300 | - int maxlen = in_len; /* The utf8->nls conversion can't make more chars */ | ||
301 | + /* The utf8->nls conversion won't make the final nls string bigger | ||
302 | + * than the utf one, but if the string is pure ascii they'll have the | ||
303 | + * same width and an extra char is needed to save the additional \0 | ||
304 | + */ | ||
305 | + int maxlen = in_len + 1; | ||
306 | |||
307 | befs_debug(sb, "---> utf2nls()"); | ||
308 | |||
309 | @@ -588,7 +592,10 @@ befs_nls2utf(struct super_block *sb, con | ||
310 | wchar_t uni; | ||
311 | int unilen, utflen; | ||
312 | char *result; | ||
313 | - int maxlen = 3 * in_len; | ||
314 | + /* There're nls characters that will translate to 3-chars-wide UTF-8 | ||
315 | + * characters, a additional byte is needed to save the final \0 | ||
316 | + * in special cases */ | ||
317 | + int maxlen = (3 * in_len) + 1; | ||
318 | |||
319 | befs_debug(sb, "---> nls2utf()\n"); | ||
320 | |||
321 | diff --git a/fs/ext3/super.c b/fs/ext3/super.c | ||
322 | index f8a5266..86534ad 100644 | ||
323 | --- a/fs/ext3/super.c | ||
324 | +++ b/fs/ext3/super.c | ||
325 | @@ -620,8 +620,48 @@ #ifdef CONFIG_QUOTA | ||
326 | #endif | ||
327 | }; | ||
328 | |||
329 | +static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp) | ||
330 | +{ | ||
331 | + __u32 *objp = vobjp; | ||
332 | + unsigned long ino = objp[0]; | ||
333 | + __u32 generation = objp[1]; | ||
334 | + struct inode *inode; | ||
335 | + struct dentry *result; | ||
336 | + | ||
337 | + if (ino != EXT3_ROOT_INO && ino < EXT3_FIRST_INO(sb)) | ||
338 | + return ERR_PTR(-ESTALE); | ||
339 | + if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) | ||
340 | + return ERR_PTR(-ESTALE); | ||
341 | + | ||
342 | + /* iget isn't really right if the inode is currently unallocated!! | ||
343 | + * ext3_read_inode currently does appropriate checks, but | ||
344 | + * it might be "neater" to call ext3_get_inode first and check | ||
345 | + * if the inode is valid..... | ||
346 | + */ | ||
347 | + inode = iget(sb, ino); | ||
348 | + if (inode == NULL) | ||
349 | + return ERR_PTR(-ENOMEM); | ||
350 | + if (is_bad_inode(inode) | ||
351 | + || (generation && inode->i_generation != generation) | ||
352 | + ) { | ||
353 | + /* we didn't find the right inode.. */ | ||
354 | + iput(inode); | ||
355 | + return ERR_PTR(-ESTALE); | ||
356 | + } | ||
357 | + /* now to find a dentry. | ||
358 | + * If possible, get a well-connected one | ||
359 | + */ | ||
360 | + result = d_alloc_anon(inode); | ||
361 | + if (!result) { | ||
362 | + iput(inode); | ||
363 | + return ERR_PTR(-ENOMEM); | ||
364 | + } | ||
365 | + return result; | ||
366 | +} | ||
367 | + | ||
368 | static struct export_operations ext3_export_ops = { | ||
369 | .get_parent = ext3_get_parent, | ||
370 | + .get_dentry = ext3_get_dentry, | ||
371 | }; | ||
372 | |||
373 | enum { | ||
374 | diff --git a/include/asm-generic/mman.h b/include/asm-generic/mman.h | ||
375 | index 3b41d2b..010ced7 100644 | ||
376 | --- a/include/asm-generic/mman.h | ||
377 | +++ b/include/asm-generic/mman.h | ||
378 | @@ -39,4 +39,10 @@ #define MADV_DOFORK 11 /* do inherit ac | ||
379 | #define MAP_ANON MAP_ANONYMOUS | ||
380 | #define MAP_FILE 0 | ||
381 | |||
382 | +#ifdef __KERNEL__ | ||
383 | +#ifndef arch_mmap_check | ||
384 | +#define arch_mmap_check(addr, len, flags) (0) | ||
385 | +#endif | ||
386 | +#endif | ||
387 | + | ||
388 | #endif | ||
389 | diff --git a/include/asm-ia64/mman.h b/include/asm-ia64/mman.h | ||
390 | index 6ba179f..df1b20e 100644 | ||
391 | --- a/include/asm-ia64/mman.h | ||
392 | +++ b/include/asm-ia64/mman.h | ||
393 | @@ -8,6 +8,12 @@ #define _ASM_IA64_MMAN_H | ||
394 | * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co | ||
395 | */ | ||
396 | |||
397 | +#ifdef __KERNEL__ | ||
398 | +#define arch_mmap_check ia64_map_check_rgn | ||
399 | +int ia64_map_check_rgn(unsigned long addr, unsigned long len, | ||
400 | + unsigned long flags); | ||
401 | +#endif | ||
402 | + | ||
403 | #include <asm-generic/mman.h> | ||
404 | |||
405 | #define MAP_GROWSDOWN 0x00100 /* stack-like segment */ | ||
406 | diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h | ||
407 | index 88d1886..95ecab5 100644 | ||
408 | --- a/include/asm-sparc/mman.h | ||
409 | +++ b/include/asm-sparc/mman.h | ||
410 | @@ -2,6 +2,12 @@ | ||
411 | #ifndef __SPARC_MMAN_H__ | ||
412 | #define __SPARC_MMAN_H__ | ||
413 | |||
414 | +#ifdef __KERNEL__ | ||
415 | +#define arch_mmap_check sparc_mmap_check | ||
416 | +int sparc_mmap_check(unsigned long addr, unsigned long len, | ||
417 | + unsigned long flags); | ||
418 | +#endif | ||
419 | + | ||
420 | #include <asm-generic/mman.h> | ||
421 | |||
422 | /* SunOS'ified... */ | ||
423 | diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h | ||
424 | index 6fd878e..b300276 100644 | ||
425 | --- a/include/asm-sparc64/mman.h | ||
426 | +++ b/include/asm-sparc64/mman.h | ||
427 | @@ -2,6 +2,12 @@ | ||
428 | #ifndef __SPARC64_MMAN_H__ | ||
429 | #define __SPARC64_MMAN_H__ | ||
430 | |||
431 | +#ifdef __KERNEL__ | ||
432 | +#define arch_mmap_check sparc64_mmap_check | ||
433 | +int sparc64_mmap_check(unsigned long addr, unsigned long len, | ||
434 | + unsigned long flags); | ||
435 | +#endif | ||
436 | + | ||
437 | #include <asm-generic/mman.h> | ||
438 | |||
439 | /* SunOS'ified... */ | ||
440 | diff --git a/kernel/timer.c b/kernel/timer.c | ||
441 | index 9e49dee..7bdad89 100644 | ||
442 | --- a/kernel/timer.c | ||
443 | +++ b/kernel/timer.c | ||
444 | @@ -975,46 +975,19 @@ asmlinkage long sys_getpid(void) | ||
445 | } | ||
446 | |||
447 | /* | ||
448 | - * Accessing ->group_leader->real_parent is not SMP-safe, it could | ||
449 | - * change from under us. However, rather than getting any lock | ||
450 | - * we can use an optimistic algorithm: get the parent | ||
451 | - * pid, and go back and check that the parent is still | ||
452 | - * the same. If it has changed (which is extremely unlikely | ||
453 | - * indeed), we just try again.. | ||
454 | - * | ||
455 | - * NOTE! This depends on the fact that even if we _do_ | ||
456 | - * get an old value of "parent", we can happily dereference | ||
457 | - * the pointer (it was and remains a dereferencable kernel pointer | ||
458 | - * no matter what): we just can't necessarily trust the result | ||
459 | - * until we know that the parent pointer is valid. | ||
460 | - * | ||
461 | - * NOTE2: ->group_leader never changes from under us. | ||
462 | + * Accessing ->real_parent is not SMP-safe, it could | ||
463 | + * change from under us. However, we can use a stale | ||
464 | + * value of ->real_parent under rcu_read_lock(), see | ||
465 | + * release_task()->call_rcu(delayed_put_task_struct). | ||
466 | */ | ||
467 | asmlinkage long sys_getppid(void) | ||
468 | { | ||
469 | int pid; | ||
470 | - struct task_struct *me = current; | ||
471 | - struct task_struct *parent; | ||
472 | |||
473 | - parent = me->group_leader->real_parent; | ||
474 | - for (;;) { | ||
475 | - pid = parent->tgid; | ||
476 | -#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) | ||
477 | -{ | ||
478 | - struct task_struct *old = parent; | ||
479 | + rcu_read_lock(); | ||
480 | + pid = rcu_dereference(current->real_parent)->tgid; | ||
481 | + rcu_read_unlock(); | ||
482 | |||
483 | - /* | ||
484 | - * Make sure we read the pid before re-reading the | ||
485 | - * parent pointer: | ||
486 | - */ | ||
487 | - smp_rmb(); | ||
488 | - parent = me->group_leader->real_parent; | ||
489 | - if (old != parent) | ||
490 | - continue; | ||
491 | -} | ||
492 | -#endif | ||
493 | - break; | ||
494 | - } | ||
495 | return pid; | ||
496 | } | ||
497 | |||
498 | diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c | ||
499 | index d8b6bb4..5cbcb80 100644 | ||
500 | --- a/lib/spinlock_debug.c | ||
501 | +++ b/lib/spinlock_debug.c | ||
502 | @@ -137,6 +137,7 @@ #endif | ||
503 | |||
504 | #define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg) | ||
505 | |||
506 | +#if 0 /* __write_lock_debug() can lock up - maybe this can too? */ | ||
507 | static void __read_lock_debug(rwlock_t *lock) | ||
508 | { | ||
509 | int print_once = 1; | ||
510 | @@ -159,12 +160,12 @@ static void __read_lock_debug(rwlock_t * | ||
511 | } | ||
512 | } | ||
513 | } | ||
514 | +#endif | ||
515 | |||
516 | void _raw_read_lock(rwlock_t *lock) | ||
517 | { | ||
518 | RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); | ||
519 | - if (unlikely(!__raw_read_trylock(&lock->raw_lock))) | ||
520 | - __read_lock_debug(lock); | ||
521 | + __raw_read_lock(&lock->raw_lock); | ||
522 | } | ||
523 | |||
524 | int _raw_read_trylock(rwlock_t *lock) | ||
525 | @@ -210,6 +211,7 @@ static inline void debug_write_unlock(rw | ||
526 | lock->owner_cpu = -1; | ||
527 | } | ||
528 | |||
529 | +#if 0 /* This can cause lockups */ | ||
530 | static void __write_lock_debug(rwlock_t *lock) | ||
531 | { | ||
532 | int print_once = 1; | ||
533 | @@ -232,12 +234,12 @@ static void __write_lock_debug(rwlock_t | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | +#endif | ||
538 | |||
539 | void _raw_write_lock(rwlock_t *lock) | ||
540 | { | ||
541 | debug_write_lock_before(lock); | ||
542 | - if (unlikely(!__raw_write_trylock(&lock->raw_lock))) | ||
543 | - __write_lock_debug(lock); | ||
544 | + __raw_write_lock(&lock->raw_lock); | ||
545 | debug_write_lock_after(lock); | ||
546 | } | ||
547 | |||
548 | diff --git a/mm/mmap.c b/mm/mmap.c | ||
549 | index e6ee123..d6e9641 100644 | ||
550 | --- a/mm/mmap.c | ||
551 | +++ b/mm/mmap.c | ||
552 | @@ -913,6 +913,10 @@ unsigned long do_mmap_pgoff(struct file | ||
553 | if (!len) | ||
554 | return -EINVAL; | ||
555 | |||
556 | + error = arch_mmap_check(addr, len, flags); | ||
557 | + if (error) | ||
558 | + return error; | ||
559 | + | ||
560 | /* Careful about overflows.. */ | ||
561 | len = PAGE_ALIGN(len); | ||
562 | if (!len || len > TASK_SIZE) | ||
563 | @@ -1852,6 +1856,7 @@ unsigned long do_brk(unsigned long addr, | ||
564 | unsigned long flags; | ||
565 | struct rb_node ** rb_link, * rb_parent; | ||
566 | pgoff_t pgoff = addr >> PAGE_SHIFT; | ||
567 | + int error; | ||
568 | |||
569 | len = PAGE_ALIGN(len); | ||
570 | if (!len) | ||
571 | @@ -1860,6 +1865,12 @@ unsigned long do_brk(unsigned long addr, | ||
572 | if ((addr + len) > TASK_SIZE || (addr + len) < addr) | ||
573 | return -EINVAL; | ||
574 | |||
575 | + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; | ||
576 | + | ||
577 | + error = arch_mmap_check(addr, len, flags); | ||
578 | + if (error) | ||
579 | + return error; | ||
580 | + | ||
581 | /* | ||
582 | * mlock MCL_FUTURE? | ||
583 | */ | ||
584 | @@ -1900,8 +1911,6 @@ unsigned long do_brk(unsigned long addr, | ||
585 | if (security_vm_enough_memory(len >> PAGE_SHIFT)) | ||
586 | return -ENOMEM; | ||
587 | |||
588 | - flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; | ||
589 | - | ||
590 | /* Can we just expand an old private anonymous mapping? */ | ||
591 | if (vma_merge(mm, prev, addr, addr + len, flags, | ||
592 | NULL, NULL, pgoff, NULL)) | ||
593 | diff --git a/mm/swapfile.c b/mm/swapfile.c | ||
594 | index e5fd538..5a7760f 100644 | ||
595 | --- a/mm/swapfile.c | ||
596 | +++ b/mm/swapfile.c | ||
597 | @@ -440,11 +440,12 @@ int swap_type_of(dev_t device) | ||
598 | |||
599 | if (!(swap_info[i].flags & SWP_WRITEOK)) | ||
600 | continue; | ||
601 | + | ||
602 | if (!device) { | ||
603 | spin_unlock(&swap_lock); | ||
604 | return i; | ||
605 | } | ||
606 | - inode = swap_info->swap_file->f_dentry->d_inode; | ||
607 | + inode = swap_info[i].swap_file->f_dentry->d_inode; | ||
608 | if (S_ISBLK(inode->i_mode) && | ||
609 | device == MKDEV(imajor(inode), iminor(inode))) { | ||
610 | spin_unlock(&swap_lock); | ||
611 | diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c | ||
612 | index ee5a517..ae70123 100644 | ||
613 | --- a/net/bridge/netfilter/ebt_ulog.c | ||
614 | +++ b/net/bridge/netfilter/ebt_ulog.c | ||
615 | @@ -75,6 +75,9 @@ static void ulog_send(unsigned int nlgro | ||
616 | if (timer_pending(&ub->timer)) | ||
617 | del_timer(&ub->timer); | ||
618 | |||
619 | + if (!ub->skb) | ||
620 | + return; | ||
621 | + | ||
622 | /* last nlmsg needs NLMSG_DONE */ | ||
623 | if (ub->qlen > 1) | ||
624 | ub->lastnlh->nlmsg_type = NLMSG_DONE; | ||
625 | diff --git a/net/core/dst.c b/net/core/dst.c | ||
626 | index 470c05b..1a5e49d 100644 | ||
627 | --- a/net/core/dst.c | ||
628 | +++ b/net/core/dst.c | ||
629 | @@ -95,12 +95,11 @@ static void dst_run_gc(unsigned long dum | ||
630 | dst_gc_timer_inc = DST_GC_INC; | ||
631 | dst_gc_timer_expires = DST_GC_MIN; | ||
632 | } | ||
633 | - dst_gc_timer.expires = jiffies + dst_gc_timer_expires; | ||
634 | #if RT_CACHE_DEBUG >= 2 | ||
635 | printk("dst_total: %d/%d %ld\n", | ||
636 | atomic_read(&dst_total), delayed, dst_gc_timer_expires); | ||
637 | #endif | ||
638 | - add_timer(&dst_gc_timer); | ||
639 | + mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires); | ||
640 | |||
641 | out: | ||
642 | spin_unlock(&dst_lock); | ||
643 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c | ||
644 | index 3fcfa9c..e02f528 100644 | ||
645 | --- a/net/core/rtnetlink.c | ||
646 | +++ b/net/core/rtnetlink.c | ||
647 | @@ -395,6 +395,9 @@ static int do_setlink(struct sk_buff *sk | ||
648 | } | ||
649 | |||
650 | if (ida[IFLA_ADDRESS - 1]) { | ||
651 | + struct sockaddr *sa; | ||
652 | + int len; | ||
653 | + | ||
654 | if (!dev->set_mac_address) { | ||
655 | err = -EOPNOTSUPP; | ||
656 | goto out; | ||
657 | @@ -406,7 +409,17 @@ static int do_setlink(struct sk_buff *sk | ||
658 | if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len)) | ||
659 | goto out; | ||
660 | |||
661 | - err = dev->set_mac_address(dev, RTA_DATA(ida[IFLA_ADDRESS - 1])); | ||
662 | + len = sizeof(sa_family_t) + dev->addr_len; | ||
663 | + sa = kmalloc(len, GFP_KERNEL); | ||
664 | + if (!sa) { | ||
665 | + err = -ENOMEM; | ||
666 | + goto out; | ||
667 | + } | ||
668 | + sa->sa_family = dev->type; | ||
669 | + memcpy(sa->sa_data, RTA_DATA(ida[IFLA_ADDRESS - 1]), | ||
670 | + dev->addr_len); | ||
671 | + err = dev->set_mac_address(dev, sa); | ||
672 | + kfree(sa); | ||
673 | if (err) | ||
674 | goto out; | ||
675 | send_addr_notify = 1; | ||
676 | diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c | ||
677 | index 0f4145b..1de08c1 100644 | ||
678 | --- a/net/ipv4/fib_semantics.c | ||
679 | +++ b/net/ipv4/fib_semantics.c | ||
680 | @@ -160,7 +160,7 @@ void free_fib_info(struct fib_info *fi) | ||
681 | |||
682 | void fib_release_info(struct fib_info *fi) | ||
683 | { | ||
684 | - write_lock(&fib_info_lock); | ||
685 | + write_lock_bh(&fib_info_lock); | ||
686 | if (fi && --fi->fib_treeref == 0) { | ||
687 | hlist_del(&fi->fib_hash); | ||
688 | if (fi->fib_prefsrc) | ||
689 | @@ -173,7 +173,7 @@ void fib_release_info(struct fib_info *f | ||
690 | fi->fib_dead = 1; | ||
691 | fib_info_put(fi); | ||
692 | } | ||
693 | - write_unlock(&fib_info_lock); | ||
694 | + write_unlock_bh(&fib_info_lock); | ||
695 | } | ||
696 | |||
697 | static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) | ||
698 | @@ -599,7 +599,7 @@ static void fib_hash_move(struct hlist_h | ||
699 | unsigned int old_size = fib_hash_size; | ||
700 | unsigned int i, bytes; | ||
701 | |||
702 | - write_lock(&fib_info_lock); | ||
703 | + write_lock_bh(&fib_info_lock); | ||
704 | old_info_hash = fib_info_hash; | ||
705 | old_laddrhash = fib_info_laddrhash; | ||
706 | fib_hash_size = new_size; | ||
707 | @@ -640,7 +640,7 @@ static void fib_hash_move(struct hlist_h | ||
708 | } | ||
709 | fib_info_laddrhash = new_laddrhash; | ||
710 | |||
711 | - write_unlock(&fib_info_lock); | ||
712 | + write_unlock_bh(&fib_info_lock); | ||
713 | |||
714 | bytes = old_size * sizeof(struct hlist_head *); | ||
715 | fib_hash_free(old_info_hash, bytes); | ||
716 | @@ -822,7 +822,7 @@ link_it: | ||
717 | |||
718 | fi->fib_treeref++; | ||
719 | atomic_inc(&fi->fib_clntref); | ||
720 | - write_lock(&fib_info_lock); | ||
721 | + write_lock_bh(&fib_info_lock); | ||
722 | hlist_add_head(&fi->fib_hash, | ||
723 | &fib_info_hash[fib_info_hashfn(fi)]); | ||
724 | if (fi->fib_prefsrc) { | ||
725 | @@ -841,7 +841,7 @@ link_it: | ||
726 | head = &fib_info_devhash[hash]; | ||
727 | hlist_add_head(&nh->nh_hash, head); | ||
728 | } endfor_nexthops(fi) | ||
729 | - write_unlock(&fib_info_lock); | ||
730 | + write_unlock_bh(&fib_info_lock); | ||
731 | return fi; | ||
732 | |||
733 | err_inval: | ||
734 | diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c | ||
735 | index d0d1919..92adfeb 100644 | ||
736 | --- a/net/ipv4/netfilter/arp_tables.c | ||
737 | +++ b/net/ipv4/netfilter/arp_tables.c | ||
738 | @@ -237,7 +237,7 @@ unsigned int arpt_do_table(struct sk_buf | ||
739 | struct arpt_entry *e, *back; | ||
740 | const char *indev, *outdev; | ||
741 | void *table_base; | ||
742 | - struct xt_table_info *private = table->private; | ||
743 | + struct xt_table_info *private; | ||
744 | |||
745 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | ||
746 | if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + | ||
747 | @@ -249,6 +249,7 @@ unsigned int arpt_do_table(struct sk_buf | ||
748 | outdev = out ? out->name : nulldevname; | ||
749 | |||
750 | read_lock_bh(&table->lock); | ||
751 | + private = table->private; | ||
752 | table_base = (void *)private->entries[smp_processor_id()]; | ||
753 | e = get_entry(table_base, private->hook_entry[hook]); | ||
754 | back = get_entry(table_base, private->underflow[hook]); | ||
755 | diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c | ||
756 | index cee3397..71871c4 100644 | ||
757 | --- a/net/ipv4/netfilter/ip_tables.c | ||
758 | +++ b/net/ipv4/netfilter/ip_tables.c | ||
759 | @@ -231,7 +231,7 @@ ipt_do_table(struct sk_buff **pskb, | ||
760 | const char *indev, *outdev; | ||
761 | void *table_base; | ||
762 | struct ipt_entry *e, *back; | ||
763 | - struct xt_table_info *private = table->private; | ||
764 | + struct xt_table_info *private; | ||
765 | |||
766 | /* Initialization */ | ||
767 | ip = (*pskb)->nh.iph; | ||
768 | @@ -248,6 +248,7 @@ ipt_do_table(struct sk_buff **pskb, | ||
769 | |||
770 | read_lock_bh(&table->lock); | ||
771 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | ||
772 | + private = table->private; | ||
773 | table_base = (void *)private->entries[smp_processor_id()]; | ||
774 | e = get_entry(table_base, private->hook_entry[hook]); | ||
775 | |||
776 | diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c | ||
777 | index c84cc03..090f138 100644 | ||
778 | --- a/net/ipv4/netfilter/ipt_ULOG.c | ||
779 | +++ b/net/ipv4/netfilter/ipt_ULOG.c | ||
780 | @@ -116,6 +116,11 @@ static void ulog_send(unsigned int nlgro | ||
781 | del_timer(&ub->timer); | ||
782 | } | ||
783 | |||
784 | + if (!ub->skb) { | ||
785 | + DEBUGP("ipt_ULOG: ulog_send: nothing to send\n"); | ||
786 | + return; | ||
787 | + } | ||
788 | + | ||
789 | /* last nlmsg needs NLMSG_DONE */ | ||
790 | if (ub->qlen > 1) | ||
791 | ub->lastnlh->nlmsg_type = NLMSG_DONE; | ||
792 | diff --git a/net/ipv4/route.c b/net/ipv4/route.c | ||
793 | index cc9423d..5fe2fcf 100644 | ||
794 | --- a/net/ipv4/route.c | ||
795 | +++ b/net/ipv4/route.c | ||
796 | @@ -3144,7 +3144,7 @@ #endif | ||
797 | rhash_entries, | ||
798 | (num_physpages >= 128 * 1024) ? | ||
799 | 15 : 17, | ||
800 | - HASH_HIGHMEM, | ||
801 | + 0, | ||
802 | &rt_hash_log, | ||
803 | &rt_hash_mask, | ||
804 | 0); | ||
805 | diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c | ||
806 | index 811d998..e6a50e8 100644 | ||
807 | --- a/net/ipx/af_ipx.c | ||
808 | +++ b/net/ipx/af_ipx.c | ||
809 | @@ -1647,7 +1647,8 @@ static int ipx_rcv(struct sk_buff *skb, | ||
810 | ipx_pktsize = ntohs(ipx->ipx_pktsize); | ||
811 | |||
812 | /* Too small or invalid header? */ | ||
813 | - if (ipx_pktsize < sizeof(struct ipxhdr) || ipx_pktsize > skb->len) | ||
814 | + if (ipx_pktsize < sizeof(struct ipxhdr) | ||
815 | + || !pskb_may_pull(skb, ipx_pktsize)) | ||
816 | goto drop; | ||
817 | |||
818 | if (ipx->ipx_checksum != IPX_NO_CHECKSUM && | ||
819 | diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c | ||
820 | index 61cdda4..b59d3b2 100644 | ||
821 | --- a/net/netfilter/nfnetlink_log.c | ||
822 | +++ b/net/netfilter/nfnetlink_log.c | ||
823 | @@ -366,6 +366,9 @@ __nfulnl_send(struct nfulnl_instance *in | ||
824 | if (timer_pending(&inst->timer)) | ||
825 | del_timer(&inst->timer); | ||
826 | |||
827 | + if (!inst->skb) | ||
828 | + return 0; | ||
829 | + | ||
830 | if (inst->qlen > 1) | ||
831 | inst->lastnlh->nlmsg_type = NLMSG_DONE; | ||
832 |