1 |
Author: dsd |
2 |
Date: 2008-02-26 15:36:51 +0000 (Tue, 26 Feb 2008) |
3 |
New Revision: 1261 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/2.6.24/1002_linux-2.6.24.3.patch |
7 |
Removed: |
8 |
genpatches-2.6/trunk/2.6.24/1500_get-zero-user-pages.patch |
9 |
genpatches-2.6/trunk/2.6.24/1705_pegasos-vt8231-quirk.patch |
10 |
genpatches-2.6/trunk/2.6.24/1900_xfs-file-readdir-oops.patch |
11 |
Modified: |
12 |
genpatches-2.6/trunk/2.6.24/0000_README |
13 |
Log: |
14 |
Linux 2.6.24.3 |
15 |
|
16 |
Modified: genpatches-2.6/trunk/2.6.24/0000_README |
17 |
=================================================================== |
18 |
--- genpatches-2.6/trunk/2.6.24/0000_README 2008-02-26 14:45:18 UTC (rev 1260) |
19 |
+++ genpatches-2.6/trunk/2.6.24/0000_README 2008-02-26 15:36:51 UTC (rev 1261) |
20 |
@@ -47,22 +47,14 @@ |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 2.6.24.2 |
23 |
|
24 |
-Patch: 1500_get-zero-user-pages.patch |
25 |
-From: http://bugs.gentoo.org/209460 |
26 |
-Desc: Preventative measure against future vmsplice-like security issues |
27 |
+Patch: 1002_linux-2.6.24.2.patch |
28 |
+From: http://www.kernel.org |
29 |
+Desc: Linux 2.6.24.3 |
30 |
|
31 |
Patch: 1700_moduleparam.patch |
32 |
From: http://bugs.gentoo.org/187175 |
33 |
Desc: Fix GCC 4.2 compile failure on alpha/ia64/ppc64 |
34 |
|
35 |
-Patch: 1705_pegasos-vt8231-quirk.patch |
36 |
-From: http://bugs.gentoo.org/210455 |
37 |
-Desc: Fix 2.6.24 libata regression on Pegasos |
38 |
- |
39 |
-Patch: 1900_xfs-file-readdir-oops.patch |
40 |
-From: http://bugs.gentoo.org/208404 |
41 |
-Desc: Fix XFS crash condition |
42 |
- |
43 |
Patch: 2100_sd-sr-medium-detection.patch |
44 |
From: http://bugs.gentoo.org/196879 |
45 |
Desc: Add early medium-not-present detection in sr/sd drivers |
46 |
|
47 |
Added: genpatches-2.6/trunk/2.6.24/1002_linux-2.6.24.3.patch |
48 |
=================================================================== |
49 |
--- genpatches-2.6/trunk/2.6.24/1002_linux-2.6.24.3.patch (rev 0) |
50 |
+++ genpatches-2.6/trunk/2.6.24/1002_linux-2.6.24.3.patch 2008-02-26 15:36:51 UTC (rev 1261) |
51 |
@@ -0,0 +1,1540 @@ |
52 |
+diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c |
53 |
+index 0340a34..759c2ac 100644 |
54 |
+--- a/arch/powerpc/platforms/chrp/pci.c |
55 |
++++ b/arch/powerpc/platforms/chrp/pci.c |
56 |
+@@ -354,7 +354,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, |
57 |
+ * mode as well. The same fixup must be done to the class-code property in |
58 |
+ * the IDE node /pci@80000000/ide@C,1 |
59 |
+ */ |
60 |
+-static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
61 |
++static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
62 |
+ { |
63 |
+ u8 progif; |
64 |
+ struct pci_dev *viaisa; |
65 |
+@@ -375,4 +375,4 @@ static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
66 |
+ |
67 |
+ pci_dev_put(viaisa); |
68 |
+ } |
69 |
+-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); |
70 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); |
71 |
+diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c |
72 |
+index ba931be..5169ecc 100644 |
73 |
+--- a/arch/powerpc/platforms/powermac/feature.c |
74 |
++++ b/arch/powerpc/platforms/powermac/feature.c |
75 |
+@@ -2565,6 +2565,8 @@ static void __init probe_uninorth(void) |
76 |
+ |
77 |
+ /* Locate core99 Uni-N */ |
78 |
+ uninorth_node = of_find_node_by_name(NULL, "uni-n"); |
79 |
++ uninorth_maj = 1; |
80 |
++ |
81 |
+ /* Locate G5 u3 */ |
82 |
+ if (uninorth_node == NULL) { |
83 |
+ uninorth_node = of_find_node_by_name(NULL, "u3"); |
84 |
+@@ -2575,8 +2577,10 @@ static void __init probe_uninorth(void) |
85 |
+ uninorth_node = of_find_node_by_name(NULL, "u4"); |
86 |
+ uninorth_maj = 4; |
87 |
+ } |
88 |
+- if (uninorth_node == NULL) |
89 |
++ if (uninorth_node == NULL) { |
90 |
++ uninorth_maj = 0; |
91 |
+ return; |
92 |
++ } |
93 |
+ |
94 |
+ addrp = of_get_property(uninorth_node, "reg", NULL); |
95 |
+ if (addrp == NULL) |
96 |
+@@ -3029,3 +3033,8 @@ void pmac_resume_agp_for_card(struct pci_dev *dev) |
97 |
+ pmac_agp_resume(pmac_agp_bridge); |
98 |
+ } |
99 |
+ EXPORT_SYMBOL(pmac_resume_agp_for_card); |
100 |
++ |
101 |
++int pmac_get_uninorth_variant(void) |
102 |
++{ |
103 |
++ return uninorth_maj; |
104 |
++} |
105 |
+diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c |
106 |
+index 28c4500..d2ffbad 100644 |
107 |
+--- a/arch/s390/lib/uaccess_std.c |
108 |
++++ b/arch/s390/lib/uaccess_std.c |
109 |
+@@ -293,10 +293,10 @@ int futex_atomic_cmpxchg_std(int __user *uaddr, int oldval, int newval) |
110 |
+ |
111 |
+ asm volatile( |
112 |
+ " sacf 256\n" |
113 |
+- " cs %1,%4,0(%5)\n" |
114 |
+- "0: lr %0,%1\n" |
115 |
+- "1: sacf 0\n" |
116 |
+- EX_TABLE(0b,1b) |
117 |
++ "0: cs %1,%4,0(%5)\n" |
118 |
++ "1: lr %0,%1\n" |
119 |
++ "2: sacf 0\n" |
120 |
++ EX_TABLE(0b,2b) EX_TABLE(1b,2b) |
121 |
+ : "=d" (ret), "+d" (oldval), "=m" (*uaddr) |
122 |
+ : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) |
123 |
+ : "cc", "memory" ); |
124 |
+diff --git a/arch/sparc/lib/rwsem.S b/arch/sparc/lib/rwsem.S |
125 |
+index 2065774..f406b1f 100644 |
126 |
+--- a/arch/sparc/lib/rwsem.S |
127 |
++++ b/arch/sparc/lib/rwsem.S |
128 |
+@@ -7,7 +7,7 @@ |
129 |
+ #include <asm/ptrace.h> |
130 |
+ #include <asm/psr.h> |
131 |
+ |
132 |
+- .section .sched.text |
133 |
++ .section .sched.text, "ax" |
134 |
+ .align 4 |
135 |
+ |
136 |
+ .globl ___down_read |
137 |
+diff --git a/arch/sparc64/lib/rwsem.S b/arch/sparc64/lib/rwsem.S |
138 |
+index 75f0e6b..1a4cc56 100644 |
139 |
+--- a/arch/sparc64/lib/rwsem.S |
140 |
++++ b/arch/sparc64/lib/rwsem.S |
141 |
+@@ -6,7 +6,7 @@ |
142 |
+ |
143 |
+ #include <asm/rwsem-const.h> |
144 |
+ |
145 |
+- .section .sched.text |
146 |
++ .section .sched.text, "ax" |
147 |
+ |
148 |
+ .globl __down_read |
149 |
+ __down_read: |
150 |
+diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c |
151 |
+index c40afba..f636c1e 100644 |
152 |
+--- a/arch/x86/mm/pageattr_64.c |
153 |
++++ b/arch/x86/mm/pageattr_64.c |
154 |
+@@ -207,7 +207,7 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) |
155 |
+ if (__pa(address) < KERNEL_TEXT_SIZE) { |
156 |
+ unsigned long addr2; |
157 |
+ pgprot_t prot2; |
158 |
+- addr2 = __START_KERNEL_map + __pa(address); |
159 |
++ addr2 = __START_KERNEL_map + __pa(address) - phys_base; |
160 |
+ /* Make sure the kernel mappings stay executable */ |
161 |
+ prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); |
162 |
+ err = __change_page_attr(addr2, pfn, prot2, |
163 |
+diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c |
164 |
+index d409f67..1ebe7a3 100644 |
165 |
+--- a/drivers/macintosh/smu.c |
166 |
++++ b/drivers/macintosh/smu.c |
167 |
+@@ -85,6 +85,7 @@ struct smu_device { |
168 |
+ u32 cmd_buf_abs; /* command buffer absolute */ |
169 |
+ struct list_head cmd_list; |
170 |
+ struct smu_cmd *cmd_cur; /* pending command */ |
171 |
++ int broken_nap; |
172 |
+ struct list_head cmd_i2c_list; |
173 |
+ struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ |
174 |
+ struct timer_list i2c_timer; |
175 |
+@@ -135,6 +136,19 @@ static void smu_start_cmd(void) |
176 |
+ fend = faddr + smu->cmd_buf->length + 2; |
177 |
+ flush_inval_dcache_range(faddr, fend); |
178 |
+ |
179 |
++ |
180 |
++ /* We also disable NAP mode for the duration of the command |
181 |
++ * on U3 based machines. |
182 |
++ * This is slightly racy as it can be written back to 1 by a sysctl |
183 |
++ * but that never happens in practice. There seem to be an issue with |
184 |
++ * U3 based machines such as the iMac G5 where napping for the |
185 |
++ * whole duration of the command prevents the SMU from fetching it |
186 |
++ * from memory. This might be related to the strange i2c based |
187 |
++ * mechanism the SMU uses to access memory. |
188 |
++ */ |
189 |
++ if (smu->broken_nap) |
190 |
++ powersave_nap = 0; |
191 |
++ |
192 |
+ /* This isn't exactly a DMA mapping here, I suspect |
193 |
+ * the SMU is actually communicating with us via i2c to the |
194 |
+ * northbridge or the CPU to access RAM. |
195 |
+@@ -211,6 +225,10 @@ static irqreturn_t smu_db_intr(int irq, void *arg) |
196 |
+ misc = cmd->misc; |
197 |
+ mb(); |
198 |
+ cmd->status = rc; |
199 |
++ |
200 |
++ /* Re-enable NAP mode */ |
201 |
++ if (smu->broken_nap) |
202 |
++ powersave_nap = 1; |
203 |
+ bail: |
204 |
+ /* Start next command if any */ |
205 |
+ smu_start_cmd(); |
206 |
+@@ -461,7 +479,7 @@ int __init smu_init (void) |
207 |
+ if (np == NULL) |
208 |
+ return -ENODEV; |
209 |
+ |
210 |
+- printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); |
211 |
++ printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR); |
212 |
+ |
213 |
+ if (smu_cmdbuf_abs == 0) { |
214 |
+ printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
215 |
+@@ -533,6 +551,11 @@ int __init smu_init (void) |
216 |
+ goto fail; |
217 |
+ } |
218 |
+ |
219 |
++ /* U3 has an issue with NAP mode when issuing SMU commands */ |
220 |
++ smu->broken_nap = pmac_get_uninorth_variant() < 4; |
221 |
++ if (smu->broken_nap) |
222 |
++ printk(KERN_INFO "SMU: using NAP mode workaround\n"); |
223 |
++ |
224 |
+ sys_ctrler = SYS_CTRLER_SMU; |
225 |
+ return 0; |
226 |
+ |
227 |
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c |
228 |
+index 49a1982..75efa8b 100644 |
229 |
+--- a/drivers/net/bonding/bond_main.c |
230 |
++++ b/drivers/net/bonding/bond_main.c |
231 |
+@@ -4883,14 +4883,16 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond |
232 |
+ down_write(&bonding_rwsem); |
233 |
+ |
234 |
+ /* Check to see if the bond already exists. */ |
235 |
+- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) |
236 |
+- if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { |
237 |
+- printk(KERN_ERR DRV_NAME |
238 |
++ if (name) { |
239 |
++ list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) |
240 |
++ if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { |
241 |
++ printk(KERN_ERR DRV_NAME |
242 |
+ ": cannot add bond %s; it already exists\n", |
243 |
+- name); |
244 |
+- res = -EPERM; |
245 |
+- goto out_rtnl; |
246 |
+- } |
247 |
++ name); |
248 |
++ res = -EPERM; |
249 |
++ goto out_rtnl; |
250 |
++ } |
251 |
++ } |
252 |
+ |
253 |
+ bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", |
254 |
+ ether_setup); |
255 |
+diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h |
256 |
+index d66c605..266ec87 100644 |
257 |
+--- a/drivers/net/dl2k.h |
258 |
++++ b/drivers/net/dl2k.h |
259 |
+@@ -388,8 +388,8 @@ enum _mii_mssr { |
260 |
+ MII_MSSR_CFG_RES = 0x4000, |
261 |
+ MII_MSSR_LOCAL_RCV_STATUS = 0x2000, |
262 |
+ MII_MSSR_REMOTE_RCVR = 0x1000, |
263 |
+- MII_MSSR_LP_1000BT_HD = 0x0800, |
264 |
+- MII_MSSR_LP_1000BT_FD = 0x0400, |
265 |
++ MII_MSSR_LP_1000BT_FD = 0x0800, |
266 |
++ MII_MSSR_LP_1000BT_HD = 0x0400, |
267 |
+ MII_MSSR_IDLE_ERR_COUNT = 0x00ff, |
268 |
+ }; |
269 |
+ |
270 |
+diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c |
271 |
+index c9868e9..e94434f 100644 |
272 |
+--- a/drivers/net/pcmcia/smc91c92_cs.c |
273 |
++++ b/drivers/net/pcmcia/smc91c92_cs.c |
274 |
+@@ -559,8 +559,16 @@ static int mhz_setup(struct pcmcia_device *link) |
275 |
+ |
276 |
+ /* Read the station address from the CIS. It is stored as the last |
277 |
+ (fourth) string in the Version 1 Version/ID tuple. */ |
278 |
+- if (link->prod_id[3]) { |
279 |
+- station_addr = link->prod_id[3]; |
280 |
++ tuple->DesiredTuple = CISTPL_VERS_1; |
281 |
++ if (first_tuple(link, tuple, parse) != CS_SUCCESS) { |
282 |
++ rc = -1; |
283 |
++ goto free_cfg_mem; |
284 |
++ } |
285 |
++ /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ |
286 |
++ if (next_tuple(link, tuple, parse) != CS_SUCCESS) |
287 |
++ first_tuple(link, tuple, parse); |
288 |
++ if (parse->version_1.ns > 3) { |
289 |
++ station_addr = parse->version_1.str + parse->version_1.ofs[3]; |
290 |
+ if (cvt_ascii_address(dev, station_addr) == 0) { |
291 |
+ rc = 0; |
292 |
+ goto free_cfg_mem; |
293 |
+diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c |
294 |
+index b253b8c..8eb78be 100644 |
295 |
+--- a/drivers/scsi/gdth.c |
296 |
++++ b/drivers/scsi/gdth.c |
297 |
+@@ -4838,6 +4838,9 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios) |
298 |
+ if (error) |
299 |
+ goto out_free_coal_stat; |
300 |
+ list_add_tail(&ha->list, &gdth_instances); |
301 |
++ |
302 |
++ scsi_scan_host(shp); |
303 |
++ |
304 |
+ return 0; |
305 |
+ |
306 |
+ out_free_coal_stat: |
307 |
+@@ -4965,6 +4968,9 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) |
308 |
+ if (error) |
309 |
+ goto out_free_coal_stat; |
310 |
+ list_add_tail(&ha->list, &gdth_instances); |
311 |
++ |
312 |
++ scsi_scan_host(shp); |
313 |
++ |
314 |
+ return 0; |
315 |
+ |
316 |
+ out_free_ccb_phys: |
317 |
+@@ -5102,6 +5108,9 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) |
318 |
+ if (error) |
319 |
+ goto out_free_coal_stat; |
320 |
+ list_add_tail(&ha->list, &gdth_instances); |
321 |
++ |
322 |
++ scsi_scan_host(shp); |
323 |
++ |
324 |
+ return 0; |
325 |
+ |
326 |
+ out_free_coal_stat: |
327 |
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c |
328 |
+index a69b155..cfd859a 100644 |
329 |
+--- a/drivers/scsi/sd.c |
330 |
++++ b/drivers/scsi/sd.c |
331 |
+@@ -907,6 +907,7 @@ static int sd_done(struct scsi_cmnd *SCpnt) |
332 |
+ unsigned int xfer_size = SCpnt->request_bufflen; |
333 |
+ unsigned int good_bytes = result ? 0 : xfer_size; |
334 |
+ u64 start_lba = SCpnt->request->sector; |
335 |
++ u64 end_lba = SCpnt->request->sector + (xfer_size / 512); |
336 |
+ u64 bad_lba; |
337 |
+ struct scsi_sense_hdr sshdr; |
338 |
+ int sense_valid = 0; |
339 |
+@@ -945,26 +946,23 @@ static int sd_done(struct scsi_cmnd *SCpnt) |
340 |
+ goto out; |
341 |
+ if (xfer_size <= SCpnt->device->sector_size) |
342 |
+ goto out; |
343 |
+- switch (SCpnt->device->sector_size) { |
344 |
+- case 256: |
345 |
++ if (SCpnt->device->sector_size < 512) { |
346 |
++ /* only legitimate sector_size here is 256 */ |
347 |
+ start_lba <<= 1; |
348 |
+- break; |
349 |
+- case 512: |
350 |
+- break; |
351 |
+- case 1024: |
352 |
+- start_lba >>= 1; |
353 |
+- break; |
354 |
+- case 2048: |
355 |
+- start_lba >>= 2; |
356 |
+- break; |
357 |
+- case 4096: |
358 |
+- start_lba >>= 3; |
359 |
+- break; |
360 |
+- default: |
361 |
+- /* Print something here with limiting frequency. */ |
362 |
+- goto out; |
363 |
+- break; |
364 |
++ end_lba <<= 1; |
365 |
++ } else { |
366 |
++ /* be careful ... don't want any overflows */ |
367 |
++ u64 factor = SCpnt->device->sector_size / 512; |
368 |
++ do_div(start_lba, factor); |
369 |
++ do_div(end_lba, factor); |
370 |
+ } |
371 |
++ |
372 |
++ if (bad_lba < start_lba || bad_lba >= end_lba) |
373 |
++ /* the bad lba was reported incorrectly, we have |
374 |
++ * no idea where the error is |
375 |
++ */ |
376 |
++ goto out; |
377 |
++ |
378 |
+ /* This computation should always be done in terms of |
379 |
+ * the resolution of the device's medium. |
380 |
+ */ |
381 |
+diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c |
382 |
+index ad632f2..0647164 100644 |
383 |
+--- a/drivers/usb/class/usblp.c |
384 |
++++ b/drivers/usb/class/usblp.c |
385 |
+@@ -428,6 +428,7 @@ static int usblp_open(struct inode *inode, struct file *file) |
386 |
+ usblp->rcomplete = 0; |
387 |
+ |
388 |
+ if (handle_bidir(usblp) < 0) { |
389 |
++ usb_autopm_put_interface(intf); |
390 |
+ usblp->used = 0; |
391 |
+ file->private_data = NULL; |
392 |
+ retval = -EIO; |
393 |
+diff --git a/fs/inotify_user.c b/fs/inotify_user.c |
394 |
+index 5e00933..7253ffd 100644 |
395 |
+--- a/fs/inotify_user.c |
396 |
++++ b/fs/inotify_user.c |
397 |
+@@ -269,7 +269,7 @@ static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask, |
398 |
+ /* we can safely put the watch as we don't reference it while |
399 |
+ * generating the event |
400 |
+ */ |
401 |
+- if (mask & IN_IGNORED || mask & IN_ONESHOT) |
402 |
++ if (mask & IN_IGNORED || w->mask & IN_ONESHOT) |
403 |
+ put_inotify_watch(w); /* final put */ |
404 |
+ |
405 |
+ /* coalescing: drop this event if it is a dupe of the previous */ |
406 |
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c |
407 |
+index 51cc1bd..855b6d5 100644 |
408 |
+--- a/fs/nfs/write.c |
409 |
++++ b/fs/nfs/write.c |
410 |
+@@ -701,6 +701,17 @@ int nfs_flush_incompatible(struct file *file, struct page *page) |
411 |
+ } |
412 |
+ |
413 |
+ /* |
414 |
++ * If the page cache is marked as unsafe or invalid, then we can't rely on |
415 |
++ * the PageUptodate() flag. In this case, we will need to turn off |
416 |
++ * write optimisations that depend on the page contents being correct. |
417 |
++ */ |
418 |
++static int nfs_write_pageuptodate(struct page *page, struct inode *inode) |
419 |
++{ |
420 |
++ return PageUptodate(page) && |
421 |
++ !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA)); |
422 |
++} |
423 |
++ |
424 |
++/* |
425 |
+ * Update and possibly write a cached page of an NFS file. |
426 |
+ * |
427 |
+ * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad |
428 |
+@@ -721,10 +732,13 @@ int nfs_updatepage(struct file *file, struct page *page, |
429 |
+ (long long)(page_offset(page) +offset)); |
430 |
+ |
431 |
+ /* If we're not using byte range locks, and we know the page |
432 |
+- * is entirely in cache, it may be more efficient to avoid |
433 |
+- * fragmenting write requests. |
434 |
++ * is up to date, it may be more efficient to extend the write |
435 |
++ * to cover the entire page in order to avoid fragmentation |
436 |
++ * inefficiencies. |
437 |
+ */ |
438 |
+- if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { |
439 |
++ if (nfs_write_pageuptodate(page, inode) && |
440 |
++ inode->i_flock == NULL && |
441 |
++ !(file->f_mode & O_SYNC)) { |
442 |
+ count = max(count + offset, nfs_page_length(page)); |
443 |
+ offset = 0; |
444 |
+ } |
445 |
+diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c |
446 |
+index 21a1c2b..edab1ff 100644 |
447 |
+--- a/fs/xfs/linux-2.6/xfs_file.c |
448 |
++++ b/fs/xfs/linux-2.6/xfs_file.c |
449 |
+@@ -350,8 +350,8 @@ xfs_file_readdir( |
450 |
+ |
451 |
+ size = buf.used; |
452 |
+ de = (struct hack_dirent *)buf.dirent; |
453 |
+- curr_offset = de->offset /* & 0x7fffffff */; |
454 |
+ while (size > 0) { |
455 |
++ curr_offset = de->offset /* & 0x7fffffff */; |
456 |
+ if (filldir(dirent, de->name, de->namlen, |
457 |
+ curr_offset & 0x7fffffff, |
458 |
+ de->ino, de->d_type)) { |
459 |
+@@ -362,7 +362,6 @@ xfs_file_readdir( |
460 |
+ sizeof(u64)); |
461 |
+ size -= reclen; |
462 |
+ de = (struct hack_dirent *)((char *)de + reclen); |
463 |
+- curr_offset = de->offset /* & 0x7fffffff */; |
464 |
+ } |
465 |
+ } |
466 |
+ |
467 |
+diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h |
468 |
+index 26bcb0a..877c35a 100644 |
469 |
+--- a/include/asm-powerpc/pmac_feature.h |
470 |
++++ b/include/asm-powerpc/pmac_feature.h |
471 |
+@@ -392,6 +392,14 @@ extern u32 __iomem *uninorth_base; |
472 |
+ #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) |
473 |
+ #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) |
474 |
+ |
475 |
++/* Uninorth variant: |
476 |
++ * |
477 |
++ * 0 = not uninorth |
478 |
++ * 1 = U1.x or U2.x |
479 |
++ * 3 = U3 |
480 |
++ * 4 = U4 |
481 |
++ */ |
482 |
++extern int pmac_get_uninorth_variant(void); |
483 |
+ |
484 |
+ #endif /* __ASM_POWERPC_PMAC_FEATURE_H */ |
485 |
+ #endif /* __KERNEL__ */ |
486 |
+diff --git a/include/linux/Kbuild b/include/linux/Kbuild |
487 |
+index f30fa92..4b32bb1 100644 |
488 |
+--- a/include/linux/Kbuild |
489 |
++++ b/include/linux/Kbuild |
490 |
+@@ -217,6 +217,7 @@ unifdef-y += i2o-dev.h |
491 |
+ unifdef-y += icmp.h |
492 |
+ unifdef-y += icmpv6.h |
493 |
+ unifdef-y += if_addr.h |
494 |
++unifdef-y += if_addrlabel.h |
495 |
+ unifdef-y += if_arp.h |
496 |
+ unifdef-y += if_bridge.h |
497 |
+ unifdef-y += if_ec.h |
498 |
+diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h |
499 |
+index 7a9398e..540799b 100644 |
500 |
+--- a/include/linux/hrtimer.h |
501 |
++++ b/include/linux/hrtimer.h |
502 |
+@@ -300,7 +300,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); |
503 |
+ |
504 |
+ /* Precise sleep: */ |
505 |
+ extern long hrtimer_nanosleep(struct timespec *rqtp, |
506 |
+- struct timespec *rmtp, |
507 |
++ struct timespec __user *rmtp, |
508 |
+ const enum hrtimer_mode mode, |
509 |
+ const clockid_t clockid); |
510 |
+ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); |
511 |
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h |
512 |
+index 30d606a..7ca198b 100644 |
513 |
+--- a/include/linux/hugetlb.h |
514 |
++++ b/include/linux/hugetlb.h |
515 |
+@@ -17,6 +17,7 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) |
516 |
+ } |
517 |
+ |
518 |
+ int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); |
519 |
++int hugetlb_overcommit_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); |
520 |
+ int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); |
521 |
+ int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); |
522 |
+ int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int); |
523 |
+diff --git a/include/linux/ktime.h b/include/linux/ktime.h |
524 |
+index a6ddec1..816cf4e 100644 |
525 |
+--- a/include/linux/ktime.h |
526 |
++++ b/include/linux/ktime.h |
527 |
+@@ -310,6 +310,8 @@ static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec) |
528 |
+ return ktime_sub_ns(kt, usec * 1000); |
529 |
+ } |
530 |
+ |
531 |
++extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs); |
532 |
++ |
533 |
+ /* |
534 |
+ * The resolution of the clocks. The resolution value is returned in |
535 |
+ * the clock_getres() system call to give application programmers an |
536 |
+diff --git a/kernel/audit.c b/kernel/audit.c |
537 |
+index f93c271..801c946 100644 |
538 |
+--- a/kernel/audit.c |
539 |
++++ b/kernel/audit.c |
540 |
+@@ -1200,13 +1200,17 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, |
541 |
+ static inline int audit_expand(struct audit_buffer *ab, int extra) |
542 |
+ { |
543 |
+ struct sk_buff *skb = ab->skb; |
544 |
+- int ret = pskb_expand_head(skb, skb_headroom(skb), extra, |
545 |
+- ab->gfp_mask); |
546 |
++ int oldtail = skb_tailroom(skb); |
547 |
++ int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask); |
548 |
++ int newtail = skb_tailroom(skb); |
549 |
++ |
550 |
+ if (ret < 0) { |
551 |
+ audit_log_lost("out of memory in audit_expand"); |
552 |
+ return 0; |
553 |
+ } |
554 |
+- return skb_tailroom(skb); |
555 |
++ |
556 |
++ skb->truesize += newtail - oldtail; |
557 |
++ return newtail; |
558 |
+ } |
559 |
+ |
560 |
+ /* |
561 |
+diff --git a/kernel/compat.c b/kernel/compat.c |
562 |
+index 42a1ed4..f2a2975 100644 |
563 |
+--- a/kernel/compat.c |
564 |
++++ b/kernel/compat.c |
565 |
+@@ -40,10 +40,36 @@ int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user |
566 |
+ __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; |
567 |
+ } |
568 |
+ |
569 |
++static long compat_nanosleep_restart(struct restart_block *restart) |
570 |
++{ |
571 |
++ struct compat_timespec __user *rmtp; |
572 |
++ struct timespec rmt; |
573 |
++ mm_segment_t oldfs; |
574 |
++ long ret; |
575 |
++ |
576 |
++ rmtp = (struct compat_timespec __user *)(restart->arg1); |
577 |
++ restart->arg1 = (unsigned long)&rmt; |
578 |
++ oldfs = get_fs(); |
579 |
++ set_fs(KERNEL_DS); |
580 |
++ ret = hrtimer_nanosleep_restart(restart); |
581 |
++ set_fs(oldfs); |
582 |
++ |
583 |
++ if (ret) { |
584 |
++ restart->fn = compat_nanosleep_restart; |
585 |
++ restart->arg1 = (unsigned long)rmtp; |
586 |
++ |
587 |
++ if (rmtp && put_compat_timespec(&rmt, rmtp)) |
588 |
++ return -EFAULT; |
589 |
++ } |
590 |
++ |
591 |
++ return ret; |
592 |
++} |
593 |
++ |
594 |
+ asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, |
595 |
+ struct compat_timespec __user *rmtp) |
596 |
+ { |
597 |
+ struct timespec tu, rmt; |
598 |
++ mm_segment_t oldfs; |
599 |
+ long ret; |
600 |
+ |
601 |
+ if (get_compat_timespec(&tu, rqtp)) |
602 |
+@@ -52,11 +78,21 @@ asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, |
603 |
+ if (!timespec_valid(&tu)) |
604 |
+ return -EINVAL; |
605 |
+ |
606 |
+- ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, |
607 |
+- CLOCK_MONOTONIC); |
608 |
++ oldfs = get_fs(); |
609 |
++ set_fs(KERNEL_DS); |
610 |
++ ret = hrtimer_nanosleep(&tu, |
611 |
++ rmtp ? (struct timespec __user *)&rmt : NULL, |
612 |
++ HRTIMER_MODE_REL, CLOCK_MONOTONIC); |
613 |
++ set_fs(oldfs); |
614 |
++ |
615 |
++ if (ret) { |
616 |
++ struct restart_block *restart |
617 |
++ = ¤t_thread_info()->restart_block; |
618 |
++ |
619 |
++ restart->fn = compat_nanosleep_restart; |
620 |
++ restart->arg1 = (unsigned long)rmtp; |
621 |
+ |
622 |
+- if (ret && rmtp) { |
623 |
+- if (put_compat_timespec(&rmt, rmtp)) |
624 |
++ if (rmtp && put_compat_timespec(&rmt, rmtp)) |
625 |
+ return -EFAULT; |
626 |
+ } |
627 |
+ |
628 |
+diff --git a/kernel/futex.c b/kernel/futex.c |
629 |
+index db9824d..55d78b5 100644 |
630 |
+--- a/kernel/futex.c |
631 |
++++ b/kernel/futex.c |
632 |
+@@ -2094,7 +2094,7 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, |
633 |
+ |
634 |
+ t = timespec_to_ktime(ts); |
635 |
+ if (cmd == FUTEX_WAIT) |
636 |
+- t = ktime_add(ktime_get(), t); |
637 |
++ t = ktime_add_safe(ktime_get(), t); |
638 |
+ tp = &t; |
639 |
+ } |
640 |
+ /* |
641 |
+diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c |
642 |
+index 0a43def..8682c79 100644 |
643 |
+--- a/kernel/futex_compat.c |
644 |
++++ b/kernel/futex_compat.c |
645 |
+@@ -175,7 +175,7 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, |
646 |
+ |
647 |
+ t = timespec_to_ktime(ts); |
648 |
+ if (cmd == FUTEX_WAIT) |
649 |
+- t = ktime_add(ktime_get(), t); |
650 |
++ t = ktime_add_safe(ktime_get(), t); |
651 |
+ tp = &t; |
652 |
+ } |
653 |
+ if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) |
654 |
+diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c |
655 |
+index f994bb8..2429893 100644 |
656 |
+--- a/kernel/hrtimer.c |
657 |
++++ b/kernel/hrtimer.c |
658 |
+@@ -325,6 +325,24 @@ unsigned long ktime_divns(const ktime_t kt, s64 div) |
659 |
+ } |
660 |
+ #endif /* BITS_PER_LONG >= 64 */ |
661 |
+ |
662 |
++/* |
663 |
++ * Add two ktime values and do a safety check for overflow: |
664 |
++ */ |
665 |
++ |
666 |
++ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) |
667 |
++{ |
668 |
++ ktime_t res = ktime_add(lhs, rhs); |
669 |
++ |
670 |
++ /* |
671 |
++ * We use KTIME_SEC_MAX here, the maximum timeout which we can |
672 |
++ * return to user space in a timespec: |
673 |
++ */ |
674 |
++ if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) |
675 |
++ res = ktime_set(KTIME_SEC_MAX, 0); |
676 |
++ |
677 |
++ return res; |
678 |
++} |
679 |
++ |
680 |
+ /* High resolution timer related functions */ |
681 |
+ #ifdef CONFIG_HIGH_RES_TIMERS |
682 |
+ |
683 |
+@@ -409,6 +427,8 @@ static int hrtimer_reprogram(struct hrtimer *timer, |
684 |
+ ktime_t expires = ktime_sub(timer->expires, base->offset); |
685 |
+ int res; |
686 |
+ |
687 |
++ WARN_ON_ONCE(timer->expires.tv64 < 0); |
688 |
++ |
689 |
+ /* |
690 |
+ * When the callback is running, we do not reprogram the clock event |
691 |
+ * device. The timer callback is either running on a different CPU or |
692 |
+@@ -419,6 +439,15 @@ static int hrtimer_reprogram(struct hrtimer *timer, |
693 |
+ if (hrtimer_callback_running(timer)) |
694 |
+ return 0; |
695 |
+ |
696 |
++ /* |
697 |
++ * CLOCK_REALTIME timer might be requested with an absolute |
698 |
++ * expiry time which is less than base->offset. Nothing wrong |
699 |
++ * about that, just avoid to call into the tick code, which |
700 |
++ * has now objections against negative expiry values. |
701 |
++ */ |
702 |
++ if (expires.tv64 < 0) |
703 |
++ return -ETIME; |
704 |
++ |
705 |
+ if (expires.tv64 >= expires_next->tv64) |
706 |
+ return 0; |
707 |
+ |
708 |
+@@ -682,13 +711,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) |
709 |
+ */ |
710 |
+ orun++; |
711 |
+ } |
712 |
+- timer->expires = ktime_add(timer->expires, interval); |
713 |
+- /* |
714 |
+- * Make sure, that the result did not wrap with a very large |
715 |
+- * interval. |
716 |
+- */ |
717 |
+- if (timer->expires.tv64 < 0) |
718 |
+- timer->expires = ktime_set(KTIME_SEC_MAX, 0); |
719 |
++ timer->expires = ktime_add_safe(timer->expires, interval); |
720 |
+ |
721 |
+ return orun; |
722 |
+ } |
723 |
+@@ -839,7 +862,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) |
724 |
+ new_base = switch_hrtimer_base(timer, base); |
725 |
+ |
726 |
+ if (mode == HRTIMER_MODE_REL) { |
727 |
+- tim = ktime_add(tim, new_base->get_time()); |
728 |
++ tim = ktime_add_safe(tim, new_base->get_time()); |
729 |
+ /* |
730 |
+ * CONFIG_TIME_LOW_RES is a temporary way for architectures |
731 |
+ * to signal that they simply return xtime in |
732 |
+@@ -848,16 +871,8 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) |
733 |
+ * timeouts. This will go away with the GTOD framework. |
734 |
+ */ |
735 |
+ #ifdef CONFIG_TIME_LOW_RES |
736 |
+- tim = ktime_add(tim, base->resolution); |
737 |
++ tim = ktime_add_safe(tim, base->resolution); |
738 |
+ #endif |
739 |
+- /* |
740 |
+- * Careful here: User space might have asked for a |
741 |
+- * very long sleep, so the add above might result in a |
742 |
+- * negative number, which enqueues the timer in front |
743 |
+- * of the queue. |
744 |
+- */ |
745 |
+- if (tim.tv64 < 0) |
746 |
+- tim.tv64 = KTIME_MAX; |
747 |
+ } |
748 |
+ timer->expires = tim; |
749 |
+ |
750 |
+@@ -1291,11 +1306,26 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod |
751 |
+ return t->task == NULL; |
752 |
+ } |
753 |
+ |
754 |
++static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp) |
755 |
++{ |
756 |
++ struct timespec rmt; |
757 |
++ ktime_t rem; |
758 |
++ |
759 |
++ rem = ktime_sub(timer->expires, timer->base->get_time()); |
760 |
++ if (rem.tv64 <= 0) |
761 |
++ return 0; |
762 |
++ rmt = ktime_to_timespec(rem); |
763 |
++ |
764 |
++ if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) |
765 |
++ return -EFAULT; |
766 |
++ |
767 |
++ return 1; |
768 |
++} |
769 |
++ |
770 |
+ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) |
771 |
+ { |
772 |
+ struct hrtimer_sleeper t; |
773 |
+- struct timespec *rmtp; |
774 |
+- ktime_t time; |
775 |
++ struct timespec __user *rmtp; |
776 |
+ |
777 |
+ restart->fn = do_no_restart_syscall; |
778 |
+ |
779 |
+@@ -1305,12 +1335,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) |
780 |
+ if (do_nanosleep(&t, HRTIMER_MODE_ABS)) |
781 |
+ return 0; |
782 |
+ |
783 |
+- rmtp = (struct timespec *)restart->arg1; |
784 |
++ rmtp = (struct timespec __user *)restart->arg1; |
785 |
+ if (rmtp) { |
786 |
+- time = ktime_sub(t.timer.expires, t.timer.base->get_time()); |
787 |
+- if (time.tv64 <= 0) |
788 |
+- return 0; |
789 |
+- *rmtp = ktime_to_timespec(time); |
790 |
++ int ret = update_rmtp(&t.timer, rmtp); |
791 |
++ if (ret <= 0) |
792 |
++ return ret; |
793 |
+ } |
794 |
+ |
795 |
+ restart->fn = hrtimer_nanosleep_restart; |
796 |
+@@ -1319,12 +1348,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) |
797 |
+ return -ERESTART_RESTARTBLOCK; |
798 |
+ } |
799 |
+ |
800 |
+-long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, |
801 |
++long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, |
802 |
+ const enum hrtimer_mode mode, const clockid_t clockid) |
803 |
+ { |
804 |
+ struct restart_block *restart; |
805 |
+ struct hrtimer_sleeper t; |
806 |
+- ktime_t rem; |
807 |
+ |
808 |
+ hrtimer_init(&t.timer, clockid, mode); |
809 |
+ t.timer.expires = timespec_to_ktime(*rqtp); |
810 |
+@@ -1336,10 +1364,9 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, |
811 |
+ return -ERESTARTNOHAND; |
812 |
+ |
813 |
+ if (rmtp) { |
814 |
+- rem = ktime_sub(t.timer.expires, t.timer.base->get_time()); |
815 |
+- if (rem.tv64 <= 0) |
816 |
+- return 0; |
817 |
+- *rmtp = ktime_to_timespec(rem); |
818 |
++ int ret = update_rmtp(&t.timer, rmtp); |
819 |
++ if (ret <= 0) |
820 |
++ return ret; |
821 |
+ } |
822 |
+ |
823 |
+ restart = ¤t_thread_info()->restart_block; |
824 |
+@@ -1355,8 +1382,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, |
825 |
+ asmlinkage long |
826 |
+ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) |
827 |
+ { |
828 |
+- struct timespec tu, rmt; |
829 |
+- int ret; |
830 |
++ struct timespec tu; |
831 |
+ |
832 |
+ if (copy_from_user(&tu, rqtp, sizeof(tu))) |
833 |
+ return -EFAULT; |
834 |
+@@ -1364,15 +1390,7 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) |
835 |
+ if (!timespec_valid(&tu)) |
836 |
+ return -EINVAL; |
837 |
+ |
838 |
+- ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, |
839 |
+- CLOCK_MONOTONIC); |
840 |
+- |
841 |
+- if (ret && rmtp) { |
842 |
+- if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) |
843 |
+- return -EFAULT; |
844 |
+- } |
845 |
+- |
846 |
+- return ret; |
847 |
++ return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); |
848 |
+ } |
849 |
+ |
850 |
+ /* |
851 |
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c |
852 |
+index 44019ce..465c69c 100644 |
853 |
+--- a/kernel/irq/chip.c |
854 |
++++ b/kernel/irq/chip.c |
855 |
+@@ -246,6 +246,17 @@ static unsigned int default_startup(unsigned int irq) |
856 |
+ } |
857 |
+ |
858 |
+ /* |
859 |
++ * default shutdown function |
860 |
++ */ |
861 |
++static void default_shutdown(unsigned int irq) |
862 |
++{ |
863 |
++ struct irq_desc *desc = irq_desc + irq; |
864 |
++ |
865 |
++ desc->chip->mask(irq); |
866 |
++ desc->status |= IRQ_MASKED; |
867 |
++} |
868 |
++ |
869 |
++/* |
870 |
+ * Fixup enable/disable function pointers |
871 |
+ */ |
872 |
+ void irq_chip_set_defaults(struct irq_chip *chip) |
873 |
+@@ -256,8 +267,15 @@ void irq_chip_set_defaults(struct irq_chip *chip) |
874 |
+ chip->disable = default_disable; |
875 |
+ if (!chip->startup) |
876 |
+ chip->startup = default_startup; |
877 |
++ /* |
878 |
++ * We use chip->disable, when the user provided its own. When |
879 |
++ * we have default_disable set for chip->disable, then we need |
880 |
++ * to use default_shutdown, otherwise the irq line is not |
881 |
++ * disabled on free_irq(): |
882 |
++ */ |
883 |
+ if (!chip->shutdown) |
884 |
+- chip->shutdown = chip->disable; |
885 |
++ chip->shutdown = chip->disable != default_disable ? |
886 |
++ chip->disable : default_shutdown; |
887 |
+ if (!chip->name) |
888 |
+ chip->name = chip->typename; |
889 |
+ if (!chip->end) |
890 |
+diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c |
891 |
+index 35b4bbf..9076432 100644 |
892 |
+--- a/kernel/posix-timers.c |
893 |
++++ b/kernel/posix-timers.c |
894 |
+@@ -766,9 +766,11 @@ common_timer_set(struct k_itimer *timr, int flags, |
895 |
+ /* SIGEV_NONE timers are not queued ! See common_timer_get */ |
896 |
+ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { |
897 |
+ /* Setup correct expiry time for relative timers */ |
898 |
+- if (mode == HRTIMER_MODE_REL) |
899 |
+- timer->expires = ktime_add(timer->expires, |
900 |
+- timer->base->get_time()); |
901 |
++ if (mode == HRTIMER_MODE_REL) { |
902 |
++ timer->expires = |
903 |
++ ktime_add_safe(timer->expires, |
904 |
++ timer->base->get_time()); |
905 |
++ } |
906 |
+ return 0; |
907 |
+ } |
908 |
+ |
909 |
+@@ -981,20 +983,9 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) |
910 |
+ static int common_nsleep(const clockid_t which_clock, int flags, |
911 |
+ struct timespec *tsave, struct timespec __user *rmtp) |
912 |
+ { |
913 |
+- struct timespec rmt; |
914 |
+- int ret; |
915 |
+- |
916 |
+- ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL, |
917 |
+- flags & TIMER_ABSTIME ? |
918 |
+- HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
919 |
+- which_clock); |
920 |
+- |
921 |
+- if (ret && rmtp) { |
922 |
+- if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) |
923 |
+- return -EFAULT; |
924 |
+- } |
925 |
+- |
926 |
+- return ret; |
927 |
++ return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ? |
928 |
++ HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
929 |
++ which_clock); |
930 |
+ } |
931 |
+ |
932 |
+ asmlinkage long |
933 |
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c |
934 |
+index c68f68d..e3e0ee3 100644 |
935 |
+--- a/kernel/sysctl.c |
936 |
++++ b/kernel/sysctl.c |
937 |
+@@ -910,7 +910,7 @@ static struct ctl_table vm_table[] = { |
938 |
+ .data = &nr_overcommit_huge_pages, |
939 |
+ .maxlen = sizeof(nr_overcommit_huge_pages), |
940 |
+ .mode = 0644, |
941 |
+- .proc_handler = &proc_doulongvec_minmax, |
942 |
++ .proc_handler = &hugetlb_overcommit_handler, |
943 |
+ }, |
944 |
+ #endif |
945 |
+ { |
946 |
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
947 |
+index db861d8..9c746cb 100644 |
948 |
+--- a/mm/hugetlb.c |
949 |
++++ b/mm/hugetlb.c |
950 |
+@@ -605,6 +605,16 @@ int hugetlb_treat_movable_handler(struct ctl_table *table, int write, |
951 |
+ return 0; |
952 |
+ } |
953 |
+ |
954 |
++int hugetlb_overcommit_handler(struct ctl_table *table, int write, |
955 |
++ struct file *file, void __user *buffer, |
956 |
++ size_t *length, loff_t *ppos) |
957 |
++{ |
958 |
++ spin_lock(&hugetlb_lock); |
959 |
++ proc_doulongvec_minmax(table, write, file, buffer, length, ppos); |
960 |
++ spin_unlock(&hugetlb_lock); |
961 |
++ return 0; |
962 |
++} |
963 |
++ |
964 |
+ #endif /* CONFIG_SYSCTL */ |
965 |
+ |
966 |
+ int hugetlb_report_meminfo(char *buf) |
967 |
+diff --git a/mm/memory.c b/mm/memory.c |
968 |
+index 4b0144b..da8b74b 100644 |
969 |
+--- a/mm/memory.c |
970 |
++++ b/mm/memory.c |
971 |
+@@ -980,6 +980,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
972 |
+ int i; |
973 |
+ unsigned int vm_flags; |
974 |
+ |
975 |
++ if (len <= 0) |
976 |
++ return 0; |
977 |
+ /* |
978 |
+ * Require read or write permissions. |
979 |
+ * If 'force' is set, we only require the "MAY" flags. |
980 |
+diff --git a/mm/slub.c b/mm/slub.c |
981 |
+index 474945e..c432f68 100644 |
982 |
+--- a/mm/slub.c |
983 |
++++ b/mm/slub.c |
984 |
+@@ -2592,6 +2592,7 @@ EXPORT_SYMBOL(ksize); |
985 |
+ void kfree(const void *x) |
986 |
+ { |
987 |
+ struct page *page; |
988 |
++ void *object = (void *)x; |
989 |
+ |
990 |
+ if (unlikely(ZERO_OR_NULL_PTR(x))) |
991 |
+ return; |
992 |
+@@ -2601,7 +2602,7 @@ void kfree(const void *x) |
993 |
+ put_page(page); |
994 |
+ return; |
995 |
+ } |
996 |
+- slab_free(page->slab, page, (void *)x, __builtin_return_address(0)); |
997 |
++ slab_free(page->slab, page, object, __builtin_return_address(0)); |
998 |
+ } |
999 |
+ EXPORT_SYMBOL(kfree); |
1000 |
+ |
1001 |
+diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c |
1002 |
+index 17f7fb7..2726adc 100644 |
1003 |
+--- a/net/bluetooth/hci_sysfs.c |
1004 |
++++ b/net/bluetooth/hci_sysfs.c |
1005 |
+@@ -12,6 +12,8 @@ |
1006 |
+ #undef BT_DBG |
1007 |
+ #define BT_DBG(D...) |
1008 |
+ #endif |
1009 |
++static struct workqueue_struct *btaddconn; |
1010 |
++static struct workqueue_struct *btdelconn; |
1011 |
+ |
1012 |
+ static inline char *typetostr(int type) |
1013 |
+ { |
1014 |
+@@ -279,6 +281,7 @@ static void add_conn(struct work_struct *work) |
1015 |
+ struct hci_conn *conn = container_of(work, struct hci_conn, work); |
1016 |
+ int i; |
1017 |
+ |
1018 |
++ flush_workqueue(btdelconn); |
1019 |
+ if (device_add(&conn->dev) < 0) { |
1020 |
+ BT_ERR("Failed to register connection device"); |
1021 |
+ return; |
1022 |
+@@ -313,6 +316,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn) |
1023 |
+ |
1024 |
+ INIT_WORK(&conn->work, add_conn); |
1025 |
+ |
1026 |
++ queue_work(btaddconn, &conn->work); |
1027 |
+ schedule_work(&conn->work); |
1028 |
+ } |
1029 |
+ |
1030 |
+@@ -349,6 +353,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn) |
1031 |
+ |
1032 |
+ INIT_WORK(&conn->work, del_conn); |
1033 |
+ |
1034 |
++ queue_work(btdelconn, &conn->work); |
1035 |
+ schedule_work(&conn->work); |
1036 |
+ } |
1037 |
+ |
1038 |
+@@ -398,31 +403,52 @@ int __init bt_sysfs_init(void) |
1039 |
+ { |
1040 |
+ int err; |
1041 |
+ |
1042 |
++ btaddconn = create_singlethread_workqueue("btaddconn"); |
1043 |
++ if (!btaddconn) { |
1044 |
++ err = -ENOMEM; |
1045 |
++ goto out; |
1046 |
++ } |
1047 |
++ btdelconn = create_singlethread_workqueue("btdelconn"); |
1048 |
++ if (!btdelconn) { |
1049 |
++ err = -ENOMEM; |
1050 |
++ goto out_del; |
1051 |
++ } |
1052 |
++ |
1053 |
+ bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); |
1054 |
+- if (IS_ERR(bt_platform)) |
1055 |
+- return PTR_ERR(bt_platform); |
1056 |
++ if (IS_ERR(bt_platform)) { |
1057 |
++ err = PTR_ERR(bt_platform); |
1058 |
++ goto out_platform; |
1059 |
++ } |
1060 |
+ |
1061 |
+ err = bus_register(&bt_bus); |
1062 |
+- if (err < 0) { |
1063 |
+- platform_device_unregister(bt_platform); |
1064 |
+- return err; |
1065 |
+- } |
1066 |
++ if (err < 0) |
1067 |
++ goto out_bus; |
1068 |
+ |
1069 |
+ bt_class = class_create(THIS_MODULE, "bluetooth"); |
1070 |
+ if (IS_ERR(bt_class)) { |
1071 |
+- bus_unregister(&bt_bus); |
1072 |
+- platform_device_unregister(bt_platform); |
1073 |
+- return PTR_ERR(bt_class); |
1074 |
++ err = PTR_ERR(bt_class); |
1075 |
++ goto out_class; |
1076 |
+ } |
1077 |
+ |
1078 |
+ return 0; |
1079 |
++ |
1080 |
++out_class: |
1081 |
++ bus_unregister(&bt_bus); |
1082 |
++out_bus: |
1083 |
++ platform_device_unregister(bt_platform); |
1084 |
++out_platform: |
1085 |
++ destroy_workqueue(btdelconn); |
1086 |
++out_del: |
1087 |
++ destroy_workqueue(btaddconn); |
1088 |
++out: |
1089 |
++ return err; |
1090 |
+ } |
1091 |
+ |
1092 |
+ void bt_sysfs_cleanup(void) |
1093 |
+ { |
1094 |
++ destroy_workqueue(btaddconn); |
1095 |
++ destroy_workqueue(btdelconn); |
1096 |
+ class_destroy(bt_class); |
1097 |
+- |
1098 |
+ bus_unregister(&bt_bus); |
1099 |
+- |
1100 |
+ platform_device_unregister(bt_platform); |
1101 |
+ } |
1102 |
+diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c |
1103 |
+index 0dfee27..2f78e1e 100644 |
1104 |
+--- a/net/ipv4/fib_hash.c |
1105 |
++++ b/net/ipv4/fib_hash.c |
1106 |
+@@ -434,19 +434,43 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) |
1107 |
+ |
1108 |
+ if (fa && fa->fa_tos == tos && |
1109 |
+ fa->fa_info->fib_priority == fi->fib_priority) { |
1110 |
+- struct fib_alias *fa_orig; |
1111 |
++ struct fib_alias *fa_first, *fa_match; |
1112 |
+ |
1113 |
+ err = -EEXIST; |
1114 |
+ if (cfg->fc_nlflags & NLM_F_EXCL) |
1115 |
+ goto out; |
1116 |
+ |
1117 |
++ /* We have 2 goals: |
1118 |
++ * 1. Find exact match for type, scope, fib_info to avoid |
1119 |
++ * duplicate routes |
1120 |
++ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it |
1121 |
++ */ |
1122 |
++ fa_match = NULL; |
1123 |
++ fa_first = fa; |
1124 |
++ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1125 |
++ list_for_each_entry_continue(fa, &f->fn_alias, fa_list) { |
1126 |
++ if (fa->fa_tos != tos) |
1127 |
++ break; |
1128 |
++ if (fa->fa_info->fib_priority != fi->fib_priority) |
1129 |
++ break; |
1130 |
++ if (fa->fa_type == cfg->fc_type && |
1131 |
++ fa->fa_scope == cfg->fc_scope && |
1132 |
++ fa->fa_info == fi) { |
1133 |
++ fa_match = fa; |
1134 |
++ break; |
1135 |
++ } |
1136 |
++ } |
1137 |
++ |
1138 |
+ if (cfg->fc_nlflags & NLM_F_REPLACE) { |
1139 |
+ struct fib_info *fi_drop; |
1140 |
+ u8 state; |
1141 |
+ |
1142 |
+- if (fi->fib_treeref > 1) |
1143 |
++ fa = fa_first; |
1144 |
++ if (fa_match) { |
1145 |
++ if (fa == fa_match) |
1146 |
++ err = 0; |
1147 |
+ goto out; |
1148 |
+- |
1149 |
++ } |
1150 |
+ write_lock_bh(&fib_hash_lock); |
1151 |
+ fi_drop = fa->fa_info; |
1152 |
+ fa->fa_info = fi; |
1153 |
+@@ -469,20 +493,11 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) |
1154 |
+ * uses the same scope, type, and nexthop |
1155 |
+ * information. |
1156 |
+ */ |
1157 |
+- fa_orig = fa; |
1158 |
+- fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1159 |
+- list_for_each_entry_continue(fa, &f->fn_alias, fa_list) { |
1160 |
+- if (fa->fa_tos != tos) |
1161 |
+- break; |
1162 |
+- if (fa->fa_info->fib_priority != fi->fib_priority) |
1163 |
+- break; |
1164 |
+- if (fa->fa_type == cfg->fc_type && |
1165 |
+- fa->fa_scope == cfg->fc_scope && |
1166 |
+- fa->fa_info == fi) |
1167 |
+- goto out; |
1168 |
+- } |
1169 |
++ if (fa_match) |
1170 |
++ goto out; |
1171 |
++ |
1172 |
+ if (!(cfg->fc_nlflags & NLM_F_APPEND)) |
1173 |
+- fa = fa_orig; |
1174 |
++ fa = fa_first; |
1175 |
+ } |
1176 |
+ |
1177 |
+ err = -ENOENT; |
1178 |
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c |
1179 |
+index 1010b46..fd46509 100644 |
1180 |
+--- a/net/ipv4/fib_trie.c |
1181 |
++++ b/net/ipv4/fib_trie.c |
1182 |
+@@ -1203,20 +1203,45 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1183 |
+ * and we need to allocate a new one of those as well. |
1184 |
+ */ |
1185 |
+ |
1186 |
+- if (fa && fa->fa_info->fib_priority == fi->fib_priority) { |
1187 |
+- struct fib_alias *fa_orig; |
1188 |
++ if (fa && fa->fa_tos == tos && |
1189 |
++ fa->fa_info->fib_priority == fi->fib_priority) { |
1190 |
++ struct fib_alias *fa_first, *fa_match; |
1191 |
+ |
1192 |
+ err = -EEXIST; |
1193 |
+ if (cfg->fc_nlflags & NLM_F_EXCL) |
1194 |
+ goto out; |
1195 |
+ |
1196 |
++ /* We have 2 goals: |
1197 |
++ * 1. Find exact match for type, scope, fib_info to avoid |
1198 |
++ * duplicate routes |
1199 |
++ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it |
1200 |
++ */ |
1201 |
++ fa_match = NULL; |
1202 |
++ fa_first = fa; |
1203 |
++ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1204 |
++ list_for_each_entry_continue(fa, fa_head, fa_list) { |
1205 |
++ if (fa->fa_tos != tos) |
1206 |
++ break; |
1207 |
++ if (fa->fa_info->fib_priority != fi->fib_priority) |
1208 |
++ break; |
1209 |
++ if (fa->fa_type == cfg->fc_type && |
1210 |
++ fa->fa_scope == cfg->fc_scope && |
1211 |
++ fa->fa_info == fi) { |
1212 |
++ fa_match = fa; |
1213 |
++ break; |
1214 |
++ } |
1215 |
++ } |
1216 |
++ |
1217 |
+ if (cfg->fc_nlflags & NLM_F_REPLACE) { |
1218 |
+ struct fib_info *fi_drop; |
1219 |
+ u8 state; |
1220 |
+ |
1221 |
+- if (fi->fib_treeref > 1) |
1222 |
++ fa = fa_first; |
1223 |
++ if (fa_match) { |
1224 |
++ if (fa == fa_match) |
1225 |
++ err = 0; |
1226 |
+ goto out; |
1227 |
+- |
1228 |
++ } |
1229 |
+ err = -ENOBUFS; |
1230 |
+ new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); |
1231 |
+ if (new_fa == NULL) |
1232 |
+@@ -1228,7 +1253,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1233 |
+ new_fa->fa_type = cfg->fc_type; |
1234 |
+ new_fa->fa_scope = cfg->fc_scope; |
1235 |
+ state = fa->fa_state; |
1236 |
+- new_fa->fa_state &= ~FA_S_ACCESSED; |
1237 |
++ new_fa->fa_state = state & ~FA_S_ACCESSED; |
1238 |
+ |
1239 |
+ list_replace_rcu(&fa->fa_list, &new_fa->fa_list); |
1240 |
+ alias_free_mem_rcu(fa); |
1241 |
+@@ -1245,20 +1270,11 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1242 |
+ * uses the same scope, type, and nexthop |
1243 |
+ * information. |
1244 |
+ */ |
1245 |
+- fa_orig = fa; |
1246 |
+- list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) { |
1247 |
+- if (fa->fa_tos != tos) |
1248 |
+- break; |
1249 |
+- if (fa->fa_info->fib_priority != fi->fib_priority) |
1250 |
+- break; |
1251 |
+- if (fa->fa_type == cfg->fc_type && |
1252 |
+- fa->fa_scope == cfg->fc_scope && |
1253 |
+- fa->fa_info == fi) { |
1254 |
+- goto out; |
1255 |
+- } |
1256 |
+- } |
1257 |
++ if (fa_match) |
1258 |
++ goto out; |
1259 |
++ |
1260 |
+ if (!(cfg->fc_nlflags & NLM_F_APPEND)) |
1261 |
+- fa = fa_orig; |
1262 |
++ fa = fa_first; |
1263 |
+ } |
1264 |
+ err = -ENOENT; |
1265 |
+ if (!(cfg->fc_nlflags & NLM_F_CREATE)) |
1266 |
+@@ -1614,9 +1630,8 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) |
1267 |
+ pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t); |
1268 |
+ |
1269 |
+ fa_to_delete = NULL; |
1270 |
+- fa_head = fa->fa_list.prev; |
1271 |
+- |
1272 |
+- list_for_each_entry(fa, fa_head, fa_list) { |
1273 |
++ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1274 |
++ list_for_each_entry_continue(fa, fa_head, fa_list) { |
1275 |
+ struct fib_info *fi = fa->fa_info; |
1276 |
+ |
1277 |
+ if (fa->fa_tos != tos) |
1278 |
+diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c |
1279 |
+index e468e7a..6d2979c 100644 |
1280 |
+--- a/net/ipv4/inet_diag.c |
1281 |
++++ b/net/ipv4/inet_diag.c |
1282 |
+@@ -259,8 +259,10 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, |
1283 |
+ const struct inet_diag_handler *handler; |
1284 |
+ |
1285 |
+ handler = inet_diag_lock_handler(nlh->nlmsg_type); |
1286 |
+- if (!handler) |
1287 |
+- return -ENOENT; |
1288 |
++ if (IS_ERR(handler)) { |
1289 |
++ err = PTR_ERR(handler); |
1290 |
++ goto unlock; |
1291 |
++ } |
1292 |
+ |
1293 |
+ hashinfo = handler->idiag_hashinfo; |
1294 |
+ err = -EINVAL; |
1295 |
+@@ -708,8 +710,8 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) |
1296 |
+ struct inet_hashinfo *hashinfo; |
1297 |
+ |
1298 |
+ handler = inet_diag_lock_handler(cb->nlh->nlmsg_type); |
1299 |
+- if (!handler) |
1300 |
+- goto no_handler; |
1301 |
++ if (IS_ERR(handler)) |
1302 |
++ goto unlock; |
1303 |
+ |
1304 |
+ hashinfo = handler->idiag_hashinfo; |
1305 |
+ |
1306 |
+@@ -838,7 +840,6 @@ done: |
1307 |
+ cb->args[2] = num; |
1308 |
+ unlock: |
1309 |
+ inet_diag_unlock_handler(handler); |
1310 |
+-no_handler: |
1311 |
+ return skb->len; |
1312 |
+ } |
1313 |
+ |
1314 |
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
1315 |
+index bc9e575..61c60cf 100644 |
1316 |
+--- a/net/ipv4/ip_output.c |
1317 |
++++ b/net/ipv4/ip_output.c |
1318 |
+@@ -462,6 +462,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
1319 |
+ if (skb_shinfo(skb)->frag_list) { |
1320 |
+ struct sk_buff *frag; |
1321 |
+ int first_len = skb_pagelen(skb); |
1322 |
++ int truesizes = 0; |
1323 |
+ |
1324 |
+ if (first_len - hlen > mtu || |
1325 |
+ ((first_len - hlen) & 7) || |
1326 |
+@@ -485,7 +486,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
1327 |
+ sock_hold(skb->sk); |
1328 |
+ frag->sk = skb->sk; |
1329 |
+ frag->destructor = sock_wfree; |
1330 |
+- skb->truesize -= frag->truesize; |
1331 |
++ truesizes += frag->truesize; |
1332 |
+ } |
1333 |
+ } |
1334 |
+ |
1335 |
+@@ -496,6 +497,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
1336 |
+ frag = skb_shinfo(skb)->frag_list; |
1337 |
+ skb_shinfo(skb)->frag_list = NULL; |
1338 |
+ skb->data_len = first_len - skb_headlen(skb); |
1339 |
++ skb->truesize -= truesizes; |
1340 |
+ skb->len = first_len; |
1341 |
+ iph->tot_len = htons(first_len); |
1342 |
+ iph->frag_off = htons(IP_MF); |
1343 |
+diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c |
1344 |
+index 2c44a94..80cab8c 100644 |
1345 |
+--- a/net/ipv4/ipcomp.c |
1346 |
++++ b/net/ipv4/ipcomp.c |
1347 |
+@@ -74,6 +74,7 @@ out: |
1348 |
+ |
1349 |
+ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
1350 |
+ { |
1351 |
++ int nexthdr; |
1352 |
+ int err = -ENOMEM; |
1353 |
+ struct ip_comp_hdr *ipch; |
1354 |
+ |
1355 |
+@@ -84,13 +85,15 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
1356 |
+ |
1357 |
+ /* Remove ipcomp header and decompress original payload */ |
1358 |
+ ipch = (void *)skb->data; |
1359 |
++ nexthdr = ipch->nexthdr; |
1360 |
++ |
1361 |
+ skb->transport_header = skb->network_header + sizeof(*ipch); |
1362 |
+ __skb_pull(skb, sizeof(*ipch)); |
1363 |
+ err = ipcomp_decompress(x, skb); |
1364 |
+ if (err) |
1365 |
+ goto out; |
1366 |
+ |
1367 |
+- err = ipch->nexthdr; |
1368 |
++ err = nexthdr; |
1369 |
+ |
1370 |
+ out: |
1371 |
+ return err; |
1372 |
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c |
1373 |
+index bec6fe8..16e04b7 100644 |
1374 |
+--- a/net/ipv4/sysctl_net_ipv4.c |
1375 |
++++ b/net/ipv4/sysctl_net_ipv4.c |
1376 |
+@@ -248,7 +248,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam |
1377 |
+ |
1378 |
+ tcp_get_available_congestion_control(tbl.data, tbl.maxlen); |
1379 |
+ ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen); |
1380 |
+- if (ret == 0 && newval && newlen) |
1381 |
++ if (ret == 1 && newval && newlen) |
1382 |
+ ret = tcp_set_allowed_congestion_control(tbl.data); |
1383 |
+ kfree(tbl.data); |
1384 |
+ |
1385 |
+diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c |
1386 |
+index 3268451..152f83d 100644 |
1387 |
+--- a/net/ipv4/xfrm4_tunnel.c |
1388 |
++++ b/net/ipv4/xfrm4_tunnel.c |
1389 |
+@@ -50,7 +50,7 @@ static struct xfrm_type ipip_type = { |
1390 |
+ |
1391 |
+ static int xfrm_tunnel_rcv(struct sk_buff *skb) |
1392 |
+ { |
1393 |
+- return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr); |
1394 |
++ return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr); |
1395 |
+ } |
1396 |
+ |
1397 |
+ static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) |
1398 |
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
1399 |
+index 3bef30e..2f59baa 100644 |
1400 |
+--- a/net/ipv6/ip6_output.c |
1401 |
++++ b/net/ipv6/ip6_output.c |
1402 |
+@@ -609,6 +609,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
1403 |
+ |
1404 |
+ if (skb_shinfo(skb)->frag_list) { |
1405 |
+ int first_len = skb_pagelen(skb); |
1406 |
++ int truesizes = 0; |
1407 |
+ |
1408 |
+ if (first_len - hlen > mtu || |
1409 |
+ ((first_len - hlen) & 7) || |
1410 |
+@@ -631,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
1411 |
+ sock_hold(skb->sk); |
1412 |
+ frag->sk = skb->sk; |
1413 |
+ frag->destructor = sock_wfree; |
1414 |
+- skb->truesize -= frag->truesize; |
1415 |
++ truesizes += frag->truesize; |
1416 |
+ } |
1417 |
+ } |
1418 |
+ |
1419 |
+@@ -662,6 +663,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
1420 |
+ |
1421 |
+ first_len = skb_pagelen(skb); |
1422 |
+ skb->data_len = first_len - skb_headlen(skb); |
1423 |
++ skb->truesize -= truesizes; |
1424 |
+ skb->len = first_len; |
1425 |
+ ipv6_hdr(skb)->payload_len = htons(first_len - |
1426 |
+ sizeof(struct ipv6hdr)); |
1427 |
+diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c |
1428 |
+index 0cd4056..1c5b09f 100644 |
1429 |
+--- a/net/ipv6/ipcomp6.c |
1430 |
++++ b/net/ipv6/ipcomp6.c |
1431 |
+@@ -64,6 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list); |
1432 |
+ |
1433 |
+ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
1434 |
+ { |
1435 |
++ int nexthdr; |
1436 |
+ int err = -ENOMEM; |
1437 |
+ struct ip_comp_hdr *ipch; |
1438 |
+ int plen, dlen; |
1439 |
+@@ -79,6 +80,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
1440 |
+ |
1441 |
+ /* Remove ipcomp header and decompress original payload */ |
1442 |
+ ipch = (void *)skb->data; |
1443 |
++ nexthdr = ipch->nexthdr; |
1444 |
++ |
1445 |
+ skb->transport_header = skb->network_header + sizeof(*ipch); |
1446 |
+ __skb_pull(skb, sizeof(*ipch)); |
1447 |
+ |
1448 |
+@@ -108,7 +111,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
1449 |
+ skb->truesize += dlen - plen; |
1450 |
+ __skb_put(skb, dlen - plen); |
1451 |
+ skb_copy_to_linear_data(skb, scratch, dlen); |
1452 |
+- err = ipch->nexthdr; |
1453 |
++ err = nexthdr; |
1454 |
+ |
1455 |
+ out_put_cpu: |
1456 |
+ put_cpu(); |
1457 |
+diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c |
1458 |
+index 7a3f64c..17ef459 100644 |
1459 |
+--- a/net/netfilter/nf_conntrack_proto_tcp.c |
1460 |
++++ b/net/netfilter/nf_conntrack_proto_tcp.c |
1461 |
+@@ -135,7 +135,7 @@ enum tcp_bit_set { |
1462 |
+ * CLOSE_WAIT: ACK seen (after FIN) |
1463 |
+ * LAST_ACK: FIN seen (after FIN) |
1464 |
+ * TIME_WAIT: last ACK seen |
1465 |
+- * CLOSE: closed connection |
1466 |
++ * CLOSE: closed connection (RST) |
1467 |
+ * |
1468 |
+ * LISTEN state is not used. |
1469 |
+ * |
1470 |
+@@ -834,8 +834,21 @@ static int tcp_packet(struct nf_conn *conntrack, |
1471 |
+ case TCP_CONNTRACK_SYN_SENT: |
1472 |
+ if (old_state < TCP_CONNTRACK_TIME_WAIT) |
1473 |
+ break; |
1474 |
+- if ((conntrack->proto.tcp.seen[!dir].flags & |
1475 |
+- IP_CT_TCP_FLAG_CLOSE_INIT) |
1476 |
++ /* RFC 1122: "When a connection is closed actively, |
1477 |
++ * it MUST linger in TIME-WAIT state for a time 2xMSL |
1478 |
++ * (Maximum Segment Lifetime). However, it MAY accept |
1479 |
++ * a new SYN from the remote TCP to reopen the connection |
1480 |
++ * directly from TIME-WAIT state, if..." |
1481 |
++ * We ignore the conditions because we are in the |
1482 |
++ * TIME-WAIT state anyway. |
1483 |
++ * |
1484 |
++ * Handle aborted connections: we and the server |
1485 |
++ * think there is an existing connection but the client |
1486 |
++ * aborts it and starts a new one. |
1487 |
++ */ |
1488 |
++ if (((conntrack->proto.tcp.seen[dir].flags |
1489 |
++ | conntrack->proto.tcp.seen[!dir].flags) |
1490 |
++ & IP_CT_TCP_FLAG_CLOSE_INIT) |
1491 |
+ || (conntrack->proto.tcp.last_dir == dir |
1492 |
+ && conntrack->proto.tcp.last_index == TCP_RST_SET)) { |
1493 |
+ /* Attempt to reopen a closed/aborted connection. |
1494 |
+@@ -848,18 +861,25 @@ static int tcp_packet(struct nf_conn *conntrack, |
1495 |
+ } |
1496 |
+ /* Fall through */ |
1497 |
+ case TCP_CONNTRACK_IGNORE: |
1498 |
+- /* Ignored packets: |
1499 |
++ /* Ignored packets: |
1500 |
++ * |
1501 |
++ * Our connection entry may be out of sync, so ignore |
1502 |
++ * packets which may signal the real connection between |
1503 |
++ * the client and the server. |
1504 |
+ * |
1505 |
+ * a) SYN in ORIGINAL |
1506 |
+ * b) SYN/ACK in REPLY |
1507 |
+ * c) ACK in reply direction after initial SYN in original. |
1508 |
++ * |
1509 |
++ * If the ignored packet is invalid, the receiver will send |
1510 |
++ * a RST we'll catch below. |
1511 |
+ */ |
1512 |
+ if (index == TCP_SYNACK_SET |
1513 |
+ && conntrack->proto.tcp.last_index == TCP_SYN_SET |
1514 |
+ && conntrack->proto.tcp.last_dir != dir |
1515 |
+ && ntohl(th->ack_seq) == |
1516 |
+ conntrack->proto.tcp.last_end) { |
1517 |
+- /* This SYN/ACK acknowledges a SYN that we earlier |
1518 |
++ /* b) This SYN/ACK acknowledges a SYN that we earlier |
1519 |
+ * ignored as invalid. This means that the client and |
1520 |
+ * the server are both in sync, while the firewall is |
1521 |
+ * not. We kill this session and block the SYN/ACK so |
1522 |
+@@ -884,7 +904,7 @@ static int tcp_packet(struct nf_conn *conntrack, |
1523 |
+ write_unlock_bh(&tcp_lock); |
1524 |
+ if (LOG_INVALID(IPPROTO_TCP)) |
1525 |
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL, |
1526 |
+- "nf_ct_tcp: invalid packed ignored "); |
1527 |
++ "nf_ct_tcp: invalid packet ignored "); |
1528 |
+ return NF_ACCEPT; |
1529 |
+ case TCP_CONNTRACK_MAX: |
1530 |
+ /* Invalid packet */ |
1531 |
+@@ -938,8 +958,7 @@ static int tcp_packet(struct nf_conn *conntrack, |
1532 |
+ |
1533 |
+ conntrack->proto.tcp.state = new_state; |
1534 |
+ if (old_state != new_state |
1535 |
+- && (new_state == TCP_CONNTRACK_FIN_WAIT |
1536 |
+- || new_state == TCP_CONNTRACK_CLOSE)) |
1537 |
++ && new_state == TCP_CONNTRACK_FIN_WAIT) |
1538 |
+ conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; |
1539 |
+ timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans |
1540 |
+ && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans |
1541 |
+diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c |
1542 |
+index ceda889..4d5ce77 100644 |
1543 |
+--- a/net/sched/em_meta.c |
1544 |
++++ b/net/sched/em_meta.c |
1545 |
+@@ -719,11 +719,13 @@ static int em_meta_match(struct sk_buff *skb, struct tcf_ematch *m, |
1546 |
+ |
1547 |
+ static inline void meta_delete(struct meta_match *meta) |
1548 |
+ { |
1549 |
+- struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); |
1550 |
++ if (meta) { |
1551 |
++ struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); |
1552 |
+ |
1553 |
+- if (ops && ops->destroy) { |
1554 |
+- ops->destroy(&meta->lvalue); |
1555 |
+- ops->destroy(&meta->rvalue); |
1556 |
++ if (ops && ops->destroy) { |
1557 |
++ ops->destroy(&meta->lvalue); |
1558 |
++ ops->destroy(&meta->rvalue); |
1559 |
++ } |
1560 |
+ } |
1561 |
+ |
1562 |
+ kfree(meta); |
1563 |
+diff --git a/net/sched/ematch.c b/net/sched/ematch.c |
1564 |
+index f3a104e..c856031 100644 |
1565 |
+--- a/net/sched/ematch.c |
1566 |
++++ b/net/sched/ematch.c |
1567 |
+@@ -305,10 +305,9 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, |
1568 |
+ struct tcf_ematch_tree_hdr *tree_hdr; |
1569 |
+ struct tcf_ematch *em; |
1570 |
+ |
1571 |
+- if (!rta) { |
1572 |
+- memset(tree, 0, sizeof(*tree)); |
1573 |
++ memset(tree, 0, sizeof(*tree)); |
1574 |
++ if (!rta) |
1575 |
+ return 0; |
1576 |
+- } |
1577 |
+ |
1578 |
+ if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0) |
1579 |
+ goto errout; |
1580 |
+diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c |
1581 |
+index 4bf715d..3a16aba 100644 |
1582 |
+--- a/security/selinux/ss/services.c |
1583 |
++++ b/security/selinux/ss/services.c |
1584 |
+@@ -2629,7 +2629,6 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) |
1585 |
+ |
1586 |
+ netlbl_sid_to_secattr_failure: |
1587 |
+ POLICY_RDUNLOCK; |
1588 |
+- netlbl_secattr_destroy(secattr); |
1589 |
+ return rc; |
1590 |
+ } |
1591 |
+ #endif /* CONFIG_NETLABEL */ |
1592 |
|
1593 |
Deleted: genpatches-2.6/trunk/2.6.24/1500_get-zero-user-pages.patch |
1594 |
=================================================================== |
1595 |
--- genpatches-2.6/trunk/2.6.24/1500_get-zero-user-pages.patch 2008-02-26 14:45:18 UTC (rev 1260) |
1596 |
+++ genpatches-2.6/trunk/2.6.24/1500_get-zero-user-pages.patch 2008-02-26 15:36:51 UTC (rev 1261) |
1597 |
@@ -1,43 +0,0 @@ |
1598 |
-From: Jonathan Corbet <corbet@×××.net> |
1599 |
-Date: Mon, 11 Feb 2008 23:17:33 +0000 (-0700) |
1600 |
-Subject: Be more robust about bad arguments in get_user_pages() |
1601 |
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=900cf086fd2fbad07f72f4575449e0d0958f860f |
1602 |
- |
1603 |
-Be more robust about bad arguments in get_user_pages() |
1604 |
- |
1605 |
-So I spent a while pounding my head against my monitor trying to figure |
1606 |
-out the vmsplice() vulnerability - how could a failure to check for |
1607 |
-*read* access turn into a root exploit? It turns out that it's a buffer |
1608 |
-overflow problem which is made easy by the way get_user_pages() is |
1609 |
-coded. |
1610 |
- |
1611 |
-In particular, "len" is a signed int, and it is only checked at the |
1612 |
-*end* of a do {} while() loop. So, if it is passed in as zero, the loop |
1613 |
-will execute once and decrement len to -1. At that point, the loop will |
1614 |
-proceed until the next invalid address is found; in the process, it will |
1615 |
-likely overflow the pages array passed in to get_user_pages(). |
1616 |
- |
1617 |
-I think that, if get_user_pages() has been asked to grab zero pages, |
1618 |
-that's what it should do. Thus this patch; it is, among other things, |
1619 |
-enough to block the (already fixed) root exploit and any others which |
1620 |
-might be lurking in similar code. I also think that the number of pages |
1621 |
-should be unsigned, but changing the prototype of this function probably |
1622 |
-requires some more careful review. |
1623 |
- |
1624 |
-Signed-off-by: Jonathan Corbet <corbet@×××.net> |
1625 |
-Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
1626 |
---- |
1627 |
- |
1628 |
-diff --git a/mm/memory.c b/mm/memory.c |
1629 |
-index e5628a5..717aa0e 100644 |
1630 |
---- a/mm/memory.c |
1631 |
-+++ b/mm/memory.c |
1632 |
-@@ -989,6 +989,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
1633 |
- int i; |
1634 |
- unsigned int vm_flags; |
1635 |
- |
1636 |
-+ if (len <= 0) |
1637 |
-+ return 0; |
1638 |
- /* |
1639 |
- * Require read or write permissions. |
1640 |
- * If 'force' is set, we only require the "MAY" flags. |
1641 |
|
1642 |
Deleted: genpatches-2.6/trunk/2.6.24/1705_pegasos-vt8231-quirk.patch |
1643 |
=================================================================== |
1644 |
--- genpatches-2.6/trunk/2.6.24/1705_pegasos-vt8231-quirk.patch 2008-02-26 14:45:18 UTC (rev 1260) |
1645 |
+++ genpatches-2.6/trunk/2.6.24/1705_pegasos-vt8231-quirk.patch 2008-02-26 15:36:51 UTC (rev 1261) |
1646 |
@@ -1,39 +0,0 @@ |
1647 |
-From: Olaf Hering <olaf@××××××.de> |
1648 |
-Date: Mon, 21 Jan 2008 09:39:30 +0000 (+1100) |
1649 |
-Subject: [POWERPC] Revert chrp_pci_fixup_vt8231_ata devinit to fix libata on pegasos |
1650 |
-X-Git-Tag: v2.6.25-rc1~1131^2~66 |
1651 |
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=092ca5bd61da6344f3b249754b337f2d48dfe08d |
1652 |
- |
1653 |
-[POWERPC] Revert chrp_pci_fixup_vt8231_ata devinit to fix libata on pegasos |
1654 |
- |
1655 |
-Commit 6d98bda79bea0e1be26c0767d0e9923ad3b72f2e changed the init order |
1656 |
-for chrp_pci_fixup_vt8231_ata(). |
1657 |
- |
1658 |
-It can not work anymore because either the irq is not yet set to 14 or |
1659 |
-pci_get_device() returns nothing. At least the printk() in |
1660 |
-chrp_pci_fixup_vt8231_ata() does not trigger anymore. |
1661 |
-pata_via works again on Pegasos with the change below. |
1662 |
- |
1663 |
-Signed-off-by: Olaf Hering <olaf@××××××.de> |
1664 |
-Signed-off-by: Paul Mackerras <paulus@×××××.org> |
1665 |
---- |
1666 |
- |
1667 |
-diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c |
1668 |
-index d51f83a..609c46d 100644 |
1669 |
---- a/arch/powerpc/platforms/chrp/pci.c |
1670 |
-+++ b/arch/powerpc/platforms/chrp/pci.c |
1671 |
-@@ -354,7 +354,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, |
1672 |
- * mode as well. The same fixup must be done to the class-code property in |
1673 |
- * the IDE node /pci@80000000/ide@C,1 |
1674 |
- */ |
1675 |
--static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
1676 |
-+static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
1677 |
- { |
1678 |
- u8 progif; |
1679 |
- struct pci_dev *viaisa; |
1680 |
-@@ -375,4 +375,4 @@ static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
1681 |
- |
1682 |
- pci_dev_put(viaisa); |
1683 |
- } |
1684 |
--DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); |
1685 |
-+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); |
1686 |
|
1687 |
Deleted: genpatches-2.6/trunk/2.6.24/1900_xfs-file-readdir-oops.patch |
1688 |
=================================================================== |
1689 |
--- genpatches-2.6/trunk/2.6.24/1900_xfs-file-readdir-oops.patch 2008-02-26 14:45:18 UTC (rev 1260) |
1690 |
+++ genpatches-2.6/trunk/2.6.24/1900_xfs-file-readdir-oops.patch 2008-02-26 15:36:51 UTC (rev 1261) |
1691 |
@@ -1,35 +0,0 @@ |
1692 |
-[PATCH] Possible fix for 2.6.24 xfs_file_readdir crash |
1693 |
- |
1694 |
-From: David Chinner <dgc@×××.com> |
1695 |
- |
1696 |
-It looks like we're deferencing a pointer beyond the end of a buffer |
1697 |
-if the buffer is filled exactly. This bug does not crash ia64 (even |
1698 |
-with memory poisoning enabled), which is why the targeted corner |
1699 |
-case testing I did a while back did not pick this up when fixing a |
1700 |
-similar bug a month ago. |
1701 |
- |
1702 |
-http://oss.sgi.com/archives/xfs/2008-02/msg00027.html |
1703 |
-[dsd@g.o: David says on LKML that this is heading upstream fast] |
1704 |
- |
1705 |
-Index: linux-2.6.24-gentoo/fs/xfs/linux-2.6/xfs_file.c |
1706 |
-=================================================================== |
1707 |
---- linux-2.6.24-gentoo.orig/fs/xfs/linux-2.6/xfs_file.c |
1708 |
-+++ linux-2.6.24-gentoo/fs/xfs/linux-2.6/xfs_file.c |
1709 |
-@@ -350,8 +350,8 @@ xfs_file_readdir( |
1710 |
- |
1711 |
- size = buf.used; |
1712 |
- de = (struct hack_dirent *)buf.dirent; |
1713 |
-- curr_offset = de->offset /* & 0x7fffffff */; |
1714 |
- while (size > 0) { |
1715 |
-+ curr_offset = de->offset /* & 0x7fffffff */; |
1716 |
- if (filldir(dirent, de->name, de->namlen, |
1717 |
- curr_offset & 0x7fffffff, |
1718 |
- de->ino, de->d_type)) { |
1719 |
-@@ -362,7 +362,6 @@ xfs_file_readdir( |
1720 |
- sizeof(u64)); |
1721 |
- size -= reclen; |
1722 |
- de = (struct hack_dirent *)((char *)de + reclen); |
1723 |
-- curr_offset = de->offset /* & 0x7fffffff */; |
1724 |
- } |
1725 |
- } |
1726 |
- |
1727 |
|
1728 |
-- |
1729 |
gentoo-commits@l.g.o mailing list |