Contents of /trunk/kernel26-alx/patches-2.6.27-r3/0129-2.6.27.30-all-fixes.patch
Parent Directory | Revision Log
Revision 1176 -
(show annotations)
(download)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 30177 byte(s)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 30177 byte(s)
-2.6.27-alx-r3: new magellan 0.5.2 kernel
1 | diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c |
2 | index 5259d8c..5d8fa67 100644 |
3 | --- a/arch/parisc/kernel/cache.c |
4 | +++ b/arch/parisc/kernel/cache.c |
5 | @@ -398,12 +398,13 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm); |
6 | |
7 | void clear_user_page_asm(void *page, unsigned long vaddr) |
8 | { |
9 | + unsigned long flags; |
10 | /* This function is implemented in assembly in pacache.S */ |
11 | extern void __clear_user_page_asm(void *page, unsigned long vaddr); |
12 | |
13 | - purge_tlb_start(); |
14 | + purge_tlb_start(flags); |
15 | __clear_user_page_asm(page, vaddr); |
16 | - purge_tlb_end(); |
17 | + purge_tlb_end(flags); |
18 | } |
19 | |
20 | #define FLUSH_THRESHOLD 0x80000 /* 0.5MB */ |
21 | @@ -444,20 +445,24 @@ extern void clear_user_page_asm(void *page, unsigned long vaddr); |
22 | |
23 | void clear_user_page(void *page, unsigned long vaddr, struct page *pg) |
24 | { |
25 | + unsigned long flags; |
26 | + |
27 | purge_kernel_dcache_page((unsigned long)page); |
28 | - purge_tlb_start(); |
29 | + purge_tlb_start(flags); |
30 | pdtlb_kernel(page); |
31 | - purge_tlb_end(); |
32 | + purge_tlb_end(flags); |
33 | clear_user_page_asm(page, vaddr); |
34 | } |
35 | EXPORT_SYMBOL(clear_user_page); |
36 | |
37 | void flush_kernel_dcache_page_addr(void *addr) |
38 | { |
39 | + unsigned long flags; |
40 | + |
41 | flush_kernel_dcache_page_asm(addr); |
42 | - purge_tlb_start(); |
43 | + purge_tlb_start(flags); |
44 | pdtlb_kernel(addr); |
45 | - purge_tlb_end(); |
46 | + purge_tlb_end(flags); |
47 | } |
48 | EXPORT_SYMBOL(flush_kernel_dcache_page_addr); |
49 | |
50 | @@ -490,8 +495,10 @@ void __flush_tlb_range(unsigned long sid, unsigned long start, |
51 | if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */ |
52 | flush_tlb_all(); |
53 | else { |
54 | + unsigned long flags; |
55 | + |
56 | mtsp(sid, 1); |
57 | - purge_tlb_start(); |
58 | + purge_tlb_start(flags); |
59 | if (split_tlb) { |
60 | while (npages--) { |
61 | pdtlb(start); |
62 | @@ -504,7 +511,7 @@ void __flush_tlb_range(unsigned long sid, unsigned long start, |
63 | start += PAGE_SIZE; |
64 | } |
65 | } |
66 | - purge_tlb_end(); |
67 | + purge_tlb_end(flags); |
68 | } |
69 | } |
70 | |
71 | diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c |
72 | index ccd61b9..6cc0be1 100644 |
73 | --- a/arch/parisc/kernel/pci-dma.c |
74 | +++ b/arch/parisc/kernel/pci-dma.c |
75 | @@ -90,12 +90,14 @@ static inline int map_pte_uncached(pte_t * pte, |
76 | if (end > PMD_SIZE) |
77 | end = PMD_SIZE; |
78 | do { |
79 | + unsigned long flags; |
80 | + |
81 | if (!pte_none(*pte)) |
82 | printk(KERN_ERR "map_pte_uncached: page already exists\n"); |
83 | set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC)); |
84 | - purge_tlb_start(); |
85 | + purge_tlb_start(flags); |
86 | pdtlb_kernel(orig_vaddr); |
87 | - purge_tlb_end(); |
88 | + purge_tlb_end(flags); |
89 | vaddr += PAGE_SIZE; |
90 | orig_vaddr += PAGE_SIZE; |
91 | (*paddr_ptr) += PAGE_SIZE; |
92 | @@ -168,11 +170,13 @@ static inline void unmap_uncached_pte(pmd_t * pmd, unsigned long vaddr, |
93 | if (end > PMD_SIZE) |
94 | end = PMD_SIZE; |
95 | do { |
96 | + unsigned long flags; |
97 | + |
98 | pte_t page = *pte; |
99 | pte_clear(&init_mm, vaddr, pte); |
100 | - purge_tlb_start(); |
101 | + purge_tlb_start(flags); |
102 | pdtlb_kernel(orig_vaddr); |
103 | - purge_tlb_end(); |
104 | + purge_tlb_end(flags); |
105 | vaddr += PAGE_SIZE; |
106 | orig_vaddr += PAGE_SIZE; |
107 | pte++; |
108 | diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c |
109 | index be33a54..eed133e 100644 |
110 | --- a/arch/x86/kernel/pci-gart_64.c |
111 | +++ b/arch/x86/kernel/pci-gart_64.c |
112 | @@ -658,8 +658,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info) |
113 | memset(gatt, 0, gatt_size); |
114 | agp_gatt_table = gatt; |
115 | |
116 | - enable_gart_translations(); |
117 | - |
118 | error = sysdev_class_register(&gart_sysdev_class); |
119 | if (!error) |
120 | error = sysdev_register(&device_gart); |
121 | @@ -828,6 +826,14 @@ void __init gart_iommu_init(void) |
122 | wbinvd(); |
123 | |
124 | /* |
125 | + * Now all caches are flushed and we can safely enable |
126 | + * GART hardware. Doing it early leaves the possibility |
127 | + * of stale cache entries that can lead to GART PTE |
128 | + * errors. |
129 | + */ |
130 | + enable_gart_translations(); |
131 | + |
132 | + /* |
133 | * Try to workaround a bug (thanks to BenH): |
134 | * Set unmapped entries to a scratch page instead of 0. |
135 | * Any prefetches that hit unmapped entries won't get an bus abort |
136 | diff --git a/block/Kconfig b/block/Kconfig |
137 | index 1ab7c15..150e21d 100644 |
138 | --- a/block/Kconfig |
139 | +++ b/block/Kconfig |
140 | @@ -67,9 +67,9 @@ config LSF |
141 | If unsure, say Y. |
142 | |
143 | config BLK_DEV_BSG |
144 | - bool "Block layer SG support v4 (EXPERIMENTAL)" |
145 | - depends on EXPERIMENTAL |
146 | - ---help--- |
147 | + bool "Block layer SG support v4" |
148 | + default y |
149 | + help |
150 | Saying Y here will enable generic SG (SCSI generic) v4 support |
151 | for any block device. |
152 | |
153 | @@ -79,7 +79,10 @@ config BLK_DEV_BSG |
154 | protocols (e.g. Task Management Functions and SMP in Serial |
155 | Attached SCSI). |
156 | |
157 | - If unsure, say N. |
158 | + This option is required by recent UDEV versions to properly |
159 | + access device serial numbers, etc. |
160 | + |
161 | + If unsure, say Y. |
162 | |
163 | config BLK_DEV_INTEGRITY |
164 | bool "Block layer data integrity support" |
165 | diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c |
166 | index 716370c..e56f805 100644 |
167 | --- a/drivers/firewire/fw-sbp2.c |
168 | +++ b/drivers/firewire/fw-sbp2.c |
169 | @@ -188,6 +188,12 @@ struct sbp2_target { |
170 | #define SBP2_RETRY_LIMIT 0xf /* 15 retries */ |
171 | #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ |
172 | |
173 | +/* |
174 | + * There is no transport protocol limit to the CDB length, but we implement |
175 | + * a fixed length only. 16 bytes is enough for disks larger than 2 TB. |
176 | + */ |
177 | +#define SBP2_MAX_CDB_SIZE 16 |
178 | + |
179 | /* Unit directory keys */ |
180 | #define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a |
181 | #define SBP2_CSR_FIRMWARE_REVISION 0x3c |
182 | @@ -293,7 +299,7 @@ struct sbp2_command_orb { |
183 | struct sbp2_pointer next; |
184 | struct sbp2_pointer data_descriptor; |
185 | __be32 misc; |
186 | - u8 command_block[12]; |
187 | + u8 command_block[SBP2_MAX_CDB_SIZE]; |
188 | } request; |
189 | struct scsi_cmnd *cmd; |
190 | scsi_done_fn_t done; |
191 | @@ -1159,6 +1165,8 @@ static int sbp2_probe(struct device *dev) |
192 | if (fw_device_enable_phys_dma(device) < 0) |
193 | goto fail_shost_put; |
194 | |
195 | + shost->max_cmd_len = SBP2_MAX_CDB_SIZE; |
196 | + |
197 | if (scsi_add_host(shost, &unit->device) < 0) |
198 | goto fail_shost_put; |
199 | |
200 | diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c |
201 | index d1b4985..fa72f5f 100644 |
202 | --- a/drivers/hwmon/smsc47m1.c |
203 | +++ b/drivers/hwmon/smsc47m1.c |
204 | @@ -85,6 +85,7 @@ superio_exit(void) |
205 | #define SUPERIO_REG_ACT 0x30 |
206 | #define SUPERIO_REG_BASE 0x60 |
207 | #define SUPERIO_REG_DEVID 0x20 |
208 | +#define SUPERIO_REG_DEVREV 0x21 |
209 | |
210 | /* Logical device registers */ |
211 | |
212 | @@ -428,6 +429,9 @@ static int __init smsc47m1_find(unsigned short *addr, |
213 | * The LPC47M292 (device id 0x6B) is somewhat compatible, but it |
214 | * supports a 3rd fan, and the pin configuration registers are |
215 | * unfortunately different. |
216 | + * The LPC47M233 has the same device id (0x6B) but is not compatible. |
217 | + * We check the high bit of the device revision register to |
218 | + * differentiate them. |
219 | */ |
220 | switch (val) { |
221 | case 0x51: |
222 | @@ -447,6 +451,13 @@ static int __init smsc47m1_find(unsigned short *addr, |
223 | sio_data->type = smsc47m1; |
224 | break; |
225 | case 0x6B: |
226 | + if (superio_inb(SUPERIO_REG_DEVREV) & 0x80) { |
227 | + pr_debug(DRVNAME ": " |
228 | + "Found SMSC LPC47M233, unsupported\n"); |
229 | + superio_exit(); |
230 | + return -ENODEV; |
231 | + } |
232 | + |
233 | pr_info(DRVNAME ": Found SMSC LPC47M292\n"); |
234 | sio_data->type = smsc47m2; |
235 | break; |
236 | diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c |
237 | index 1a9cc13..b96f302 100644 |
238 | --- a/drivers/i2c/chips/tsl2550.c |
239 | +++ b/drivers/i2c/chips/tsl2550.c |
240 | @@ -27,7 +27,7 @@ |
241 | #include <linux/delay.h> |
242 | |
243 | #define TSL2550_DRV_NAME "tsl2550" |
244 | -#define DRIVER_VERSION "1.1.1" |
245 | +#define DRIVER_VERSION "1.1.2" |
246 | |
247 | /* |
248 | * Defines |
249 | @@ -189,13 +189,16 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1) |
250 | u8 r = 128; |
251 | |
252 | /* Avoid division by 0 and count 1 cannot be greater than count 0 */ |
253 | - if (c0 && (c1 <= c0)) |
254 | - r = c1 * 128 / c0; |
255 | + if (c1 <= c0) |
256 | + if (c0) { |
257 | + r = c1 * 128 / c0; |
258 | + |
259 | + /* Calculate LUX */ |
260 | + lux = ((c0 - c1) * ratio_lut[r]) / 256; |
261 | + } else |
262 | + lux = 0; |
263 | else |
264 | - return -1; |
265 | - |
266 | - /* Calculate LUX */ |
267 | - lux = ((c0 - c1) * ratio_lut[r]) / 256; |
268 | + return -EAGAIN; |
269 | |
270 | /* LUX range check */ |
271 | return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; |
272 | diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c |
273 | index 0c0fdbb..e21c2d5 100644 |
274 | --- a/drivers/ieee1394/sbp2.c |
275 | +++ b/drivers/ieee1394/sbp2.c |
276 | @@ -874,6 +874,7 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud) |
277 | } |
278 | |
279 | shost->hostdata[0] = (unsigned long)lu; |
280 | + shost->max_cmd_len = SBP2_MAX_CDB_SIZE; |
281 | |
282 | if (!scsi_add_host(shost, &ud->device)) { |
283 | lu->shost = shost; |
284 | diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h |
285 | index 875428b..e547b16 100644 |
286 | --- a/drivers/ieee1394/sbp2.h |
287 | +++ b/drivers/ieee1394/sbp2.h |
288 | @@ -25,6 +25,12 @@ |
289 | #define SBP2_DEVICE_NAME "sbp2" |
290 | |
291 | /* |
292 | + * There is no transport protocol limit to the CDB length, but we implement |
293 | + * a fixed length only. 16 bytes is enough for disks larger than 2 TB. |
294 | + */ |
295 | +#define SBP2_MAX_CDB_SIZE 16 |
296 | + |
297 | +/* |
298 | * SBP-2 specific definitions |
299 | */ |
300 | |
301 | @@ -51,7 +57,7 @@ struct sbp2_command_orb { |
302 | u32 data_descriptor_hi; |
303 | u32 data_descriptor_lo; |
304 | u32 misc; |
305 | - u8 cdb[12]; |
306 | + u8 cdb[SBP2_MAX_CDB_SIZE]; |
307 | } __attribute__((packed)); |
308 | |
309 | #define SBP2_LOGIN_REQUEST 0x0 |
310 | diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig |
311 | index a726f3b..52174d9 100644 |
312 | --- a/drivers/misc/Kconfig |
313 | +++ b/drivers/misc/Kconfig |
314 | @@ -321,6 +321,7 @@ config THINKPAD_ACPI_DOCK |
315 | bool "Legacy Docking Station Support" |
316 | depends on THINKPAD_ACPI |
317 | depends on ACPI_DOCK=n |
318 | + depends on BROKEN |
319 | default n |
320 | ---help--- |
321 | Allows the thinkpad_acpi driver to handle docking station events. |
322 | @@ -334,7 +335,8 @@ config THINKPAD_ACPI_DOCK |
323 | config THINKPAD_ACPI_BAY |
324 | bool "Legacy Removable Bay Support" |
325 | depends on THINKPAD_ACPI |
326 | - default y |
327 | + depends on BROKEN |
328 | + default n |
329 | ---help--- |
330 | Allows the thinkpad_acpi driver to handle removable bays. It will |
331 | electrically disable the device in the bay, and also generate |
332 | diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c |
333 | index 375a0bd..ec4204a 100644 |
334 | --- a/drivers/net/usb/asix.c |
335 | +++ b/drivers/net/usb/asix.c |
336 | @@ -1456,6 +1456,14 @@ static const struct usb_device_id products [] = { |
337 | // ASIX 88772a |
338 | USB_DEVICE(0x0db0, 0xa877), |
339 | .driver_info = (unsigned long) &ax88772_info, |
340 | +}, { |
341 | + // ABOCOM for pci |
342 | + USB_DEVICE(0x14ea, 0xab11), |
343 | + .driver_info = (unsigned long) &ax88178_info, |
344 | +}, { |
345 | + // ASIX 88772a |
346 | + USB_DEVICE(0x0db0, 0xa877), |
347 | + .driver_info = (unsigned long) &ax88772_info, |
348 | }, |
349 | { }, // END |
350 | }; |
351 | diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c |
352 | index 139935a..ad02d57 100644 |
353 | --- a/drivers/scsi/libsas/sas_port.c |
354 | +++ b/drivers/scsi/libsas/sas_port.c |
355 | @@ -56,7 +56,7 @@ static void sas_form_port(struct asd_sas_phy *phy) |
356 | } |
357 | } |
358 | |
359 | - /* find a port */ |
360 | + /* see if the phy should be part of a wide port */ |
361 | spin_lock_irqsave(&sas_ha->phy_port_lock, flags); |
362 | for (i = 0; i < sas_ha->num_phys; i++) { |
363 | port = sas_ha->sas_port[i]; |
364 | @@ -69,12 +69,23 @@ static void sas_form_port(struct asd_sas_phy *phy) |
365 | SAS_DPRINTK("phy%d matched wide port%d\n", phy->id, |
366 | port->id); |
367 | break; |
368 | - } else if (*(u64 *) port->sas_addr == 0 && port->num_phys==0) { |
369 | - memcpy(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE); |
370 | - break; |
371 | } |
372 | spin_unlock(&port->phy_list_lock); |
373 | } |
374 | + /* The phy does not match any existing port, create a new one */ |
375 | + if (i == sas_ha->num_phys) { |
376 | + for (i = 0; i < sas_ha->num_phys; i++) { |
377 | + port = sas_ha->sas_port[i]; |
378 | + spin_lock(&port->phy_list_lock); |
379 | + if (*(u64 *)port->sas_addr == 0 |
380 | + && port->num_phys == 0) { |
381 | + memcpy(port->sas_addr, phy->sas_addr, |
382 | + SAS_ADDR_SIZE); |
383 | + break; |
384 | + } |
385 | + spin_unlock(&port->phy_list_lock); |
386 | + } |
387 | + } |
388 | |
389 | if (i >= sas_ha->num_phys) { |
390 | printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", |
391 | diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c |
392 | index 1ff88af..33b2935 100644 |
393 | --- a/drivers/usb/core/devio.c |
394 | +++ b/drivers/usb/core/devio.c |
395 | @@ -579,7 +579,7 @@ static int usbdev_open(struct inode *inode, struct file *file) |
396 | if (!ps) |
397 | goto out; |
398 | |
399 | - ret = -ENOENT; |
400 | + ret = -ENODEV; |
401 | |
402 | /* usbdev device-node */ |
403 | if (imajor(inode) == USB_DEVICE_MAJOR) |
404 | @@ -1305,7 +1305,8 @@ static int get_urb32(struct usbdevfs_urb *kurb, |
405 | struct usbdevfs_urb32 __user *uurb) |
406 | { |
407 | __u32 uptr; |
408 | - if (get_user(kurb->type, &uurb->type) || |
409 | + if (!access_ok(VERIFY_READ, uurb, sizeof(*uurb)) || |
410 | + __get_user(kurb->type, &uurb->type) || |
411 | __get_user(kurb->endpoint, &uurb->endpoint) || |
412 | __get_user(kurb->status, &uurb->status) || |
413 | __get_user(kurb->flags, &uurb->flags) || |
414 | @@ -1522,8 +1523,9 @@ static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg) |
415 | u32 udata; |
416 | |
417 | uioc = compat_ptr((long)arg); |
418 | - if (get_user(ctrl.ifno, &uioc->ifno) || |
419 | - get_user(ctrl.ioctl_code, &uioc->ioctl_code) || |
420 | + if (!access_ok(VERIFY_READ, uioc, sizeof(*uioc)) || |
421 | + __get_user(ctrl.ifno, &uioc->ifno) || |
422 | + __get_user(ctrl.ioctl_code, &uioc->ioctl_code) || |
423 | __get_user(udata, &uioc->data)) |
424 | return -EFAULT; |
425 | ctrl.data = compat_ptr(udata); |
426 | diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c |
427 | index 13b34bc..c3089c9 100644 |
428 | --- a/drivers/usb/serial/ftdi_sio.c |
429 | +++ b/drivers/usb/serial/ftdi_sio.c |
430 | @@ -663,6 +663,9 @@ static struct usb_device_id id_table_combined [] = { |
431 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), |
432 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
433 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
434 | + { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, |
435 | + { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
436 | + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
437 | { }, /* Optional parameter entry */ |
438 | { } /* Terminating entry */ |
439 | }; |
440 | diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h |
441 | index 3425122..c1a6be7 100644 |
442 | --- a/drivers/usb/serial/ftdi_sio.h |
443 | +++ b/drivers/usb/serial/ftdi_sio.h |
444 | @@ -897,6 +897,20 @@ |
445 | #define JETI_SPC1201_PID 0x04b2 |
446 | |
447 | /* |
448 | + * Bayer Ascensia Contour blood glucose meter USB-converter cable. |
449 | + * http://winglucofacts.com/cables/ |
450 | + */ |
451 | +#define BAYER_VID 0x1A79 |
452 | +#define BAYER_CONTOUR_CABLE_PID 0x6001 |
453 | + |
454 | +/* |
455 | + * Marvell OpenRD Base, Client |
456 | + * http://www.open-rd.org |
457 | + * OpenRD Base, Client use VID 0x0403 |
458 | + */ |
459 | +#define MARVELL_OPENRD_PID 0x9e90 |
460 | + |
461 | +/* |
462 | * BmRequestType: 1100 0000b |
463 | * bRequest: FTDI_E2_READ |
464 | * wValue: 0 |
465 | diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c |
466 | index 861e308..5d4f9d6 100644 |
467 | --- a/drivers/usb/storage/transport.c |
468 | +++ b/drivers/usb/storage/transport.c |
469 | @@ -961,7 +961,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us) |
470 | US_BULK_GET_MAX_LUN, |
471 | USB_DIR_IN | USB_TYPE_CLASS | |
472 | USB_RECIP_INTERFACE, |
473 | - 0, us->ifnum, us->iobuf, 1, HZ); |
474 | + 0, us->ifnum, us->iobuf, 1, 10*HZ); |
475 | |
476 | US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", |
477 | result, us->iobuf[0]); |
478 | diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h |
479 | index 65115a5..17e9626 100644 |
480 | --- a/drivers/usb/storage/unusual_devs.h |
481 | +++ b/drivers/usb/storage/unusual_devs.h |
482 | @@ -989,6 +989,13 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, |
483 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
484 | US_FL_FIX_CAPACITY ), |
485 | |
486 | +/* Reported by Rogerio Brito <rbrito@ime.usp.br> */ |
487 | +UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001, |
488 | + "Prolific Technology, Inc.", |
489 | + "Mass Storage Device", |
490 | + US_SC_DEVICE, US_PR_DEVICE, NULL, |
491 | + US_FL_NOT_LOCKABLE ), |
492 | + |
493 | /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */ |
494 | /* Change to bcdDeviceMin (0x0100 to 0x0001) reported by |
495 | * Thomas Bartosik <tbartdev@gmx-topmail.de> */ |
496 | diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c |
497 | index dfc0197..25200e6 100644 |
498 | --- a/fs/binfmt_flat.c |
499 | +++ b/fs/binfmt_flat.c |
500 | @@ -824,15 +824,22 @@ static int load_flat_shared_library(int id, struct lib_info *libs) |
501 | if (IS_ERR(bprm.file)) |
502 | return res; |
503 | |
504 | + bprm.cred = prepare_exec_creds(); |
505 | + res = -ENOMEM; |
506 | + if (!bprm.cred) |
507 | + goto out; |
508 | + |
509 | res = prepare_binprm(&bprm); |
510 | |
511 | if (res <= (unsigned long)-4096) |
512 | res = load_flat_file(&bprm, libs, id, NULL); |
513 | - if (bprm.file) { |
514 | - allow_write_access(bprm.file); |
515 | - fput(bprm.file); |
516 | - bprm.file = NULL; |
517 | - } |
518 | + |
519 | + abort_creds(bprm.cred); |
520 | + |
521 | +out: |
522 | + allow_write_access(bprm.file); |
523 | + fput(bprm.file); |
524 | + |
525 | return(res); |
526 | } |
527 | |
528 | diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c |
529 | index 61cb48f..994ca87 100644 |
530 | --- a/fs/compat_ioctl.c |
531 | +++ b/fs/compat_ioctl.c |
532 | @@ -1910,6 +1910,7 @@ COMPATIBLE_IOCTL(FIONCLEX) |
533 | COMPATIBLE_IOCTL(FIOASYNC) |
534 | COMPATIBLE_IOCTL(FIONBIO) |
535 | COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */ |
536 | +COMPATIBLE_IOCTL(FS_IOC_FIEMAP) |
537 | /* 0x00 */ |
538 | COMPATIBLE_IOCTL(FIBMAP) |
539 | COMPATIBLE_IOCTL(FIGETBSZ) |
540 | diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c |
541 | index 08f6b04..630feb3 100644 |
542 | --- a/fs/nfs/direct.c |
543 | +++ b/fs/nfs/direct.c |
544 | @@ -255,7 +255,7 @@ static void nfs_direct_read_release(void *calldata) |
545 | |
546 | if (put_dreq(dreq)) |
547 | nfs_direct_complete(dreq); |
548 | - nfs_readdata_release(calldata); |
549 | + nfs_readdata_free(data); |
550 | } |
551 | |
552 | static const struct rpc_call_ops nfs_read_direct_ops = { |
553 | @@ -311,14 +311,14 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, |
554 | data->npages, 1, 0, data->pagevec, NULL); |
555 | up_read(¤t->mm->mmap_sem); |
556 | if (result < 0) { |
557 | - nfs_readdata_release(data); |
558 | + nfs_readdata_free(data); |
559 | break; |
560 | } |
561 | if ((unsigned)result < data->npages) { |
562 | bytes = result * PAGE_SIZE; |
563 | if (bytes <= pgbase) { |
564 | nfs_direct_release_pages(data->pagevec, result); |
565 | - nfs_readdata_release(data); |
566 | + nfs_readdata_free(data); |
567 | break; |
568 | } |
569 | bytes -= pgbase; |
570 | @@ -331,7 +331,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, |
571 | data->inode = inode; |
572 | data->cred = msg.rpc_cred; |
573 | data->args.fh = NFS_FH(inode); |
574 | - data->args.context = get_nfs_open_context(ctx); |
575 | + data->args.context = ctx; |
576 | data->args.offset = pos; |
577 | data->args.pgbase = pgbase; |
578 | data->args.pages = data->pagevec; |
579 | @@ -438,7 +438,7 @@ static void nfs_direct_free_writedata(struct nfs_direct_req *dreq) |
580 | struct nfs_write_data *data = list_entry(dreq->rewrite_list.next, struct nfs_write_data, pages); |
581 | list_del(&data->pages); |
582 | nfs_direct_release_pages(data->pagevec, data->npages); |
583 | - nfs_writedata_release(data); |
584 | + nfs_writedata_free(data); |
585 | } |
586 | } |
587 | |
588 | @@ -531,7 +531,7 @@ static void nfs_direct_commit_release(void *calldata) |
589 | |
590 | dprintk("NFS: %5u commit returned %d\n", data->task.tk_pid, status); |
591 | nfs_direct_write_complete(dreq, data->inode); |
592 | - nfs_commitdata_release(calldata); |
593 | + nfs_commit_free(data); |
594 | } |
595 | |
596 | static const struct rpc_call_ops nfs_commit_direct_ops = { |
597 | @@ -564,7 +564,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) |
598 | data->args.fh = NFS_FH(data->inode); |
599 | data->args.offset = 0; |
600 | data->args.count = 0; |
601 | - data->args.context = get_nfs_open_context(dreq->ctx); |
602 | + data->args.context = dreq->ctx; |
603 | data->res.count = 0; |
604 | data->res.fattr = &data->fattr; |
605 | data->res.verf = &data->verf; |
606 | @@ -725,14 +725,14 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, |
607 | data->npages, 0, 0, data->pagevec, NULL); |
608 | up_read(¤t->mm->mmap_sem); |
609 | if (result < 0) { |
610 | - nfs_writedata_release(data); |
611 | + nfs_writedata_free(data); |
612 | break; |
613 | } |
614 | if ((unsigned)result < data->npages) { |
615 | bytes = result * PAGE_SIZE; |
616 | if (bytes <= pgbase) { |
617 | nfs_direct_release_pages(data->pagevec, result); |
618 | - nfs_writedata_release(data); |
619 | + nfs_writedata_free(data); |
620 | break; |
621 | } |
622 | bytes -= pgbase; |
623 | @@ -747,7 +747,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, |
624 | data->inode = inode; |
625 | data->cred = msg.rpc_cred; |
626 | data->args.fh = NFS_FH(inode); |
627 | - data->args.context = get_nfs_open_context(ctx); |
628 | + data->args.context = ctx; |
629 | data->args.offset = pos; |
630 | data->args.pgbase = pgbase; |
631 | data->args.pages = data->pagevec; |
632 | diff --git a/fs/nfs/read.c b/fs/nfs/read.c |
633 | index f856004..ff41222 100644 |
634 | --- a/fs/nfs/read.c |
635 | +++ b/fs/nfs/read.c |
636 | @@ -58,17 +58,15 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) |
637 | return p; |
638 | } |
639 | |
640 | -static void nfs_readdata_free(struct nfs_read_data *p) |
641 | +void nfs_readdata_free(struct nfs_read_data *p) |
642 | { |
643 | if (p && (p->pagevec != &p->page_array[0])) |
644 | kfree(p->pagevec); |
645 | mempool_free(p, nfs_rdata_mempool); |
646 | } |
647 | |
648 | -void nfs_readdata_release(void *data) |
649 | +static void nfs_readdata_release(struct nfs_read_data *rdata) |
650 | { |
651 | - struct nfs_read_data *rdata = data; |
652 | - |
653 | put_nfs_open_context(rdata->args.context); |
654 | nfs_readdata_free(rdata); |
655 | } |
656 | diff --git a/fs/nfs/write.c b/fs/nfs/write.c |
657 | index 3229e21..84f4e75 100644 |
658 | --- a/fs/nfs/write.c |
659 | +++ b/fs/nfs/write.c |
660 | @@ -84,17 +84,15 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) |
661 | return p; |
662 | } |
663 | |
664 | -static void nfs_writedata_free(struct nfs_write_data *p) |
665 | +void nfs_writedata_free(struct nfs_write_data *p) |
666 | { |
667 | if (p && (p->pagevec != &p->page_array[0])) |
668 | kfree(p->pagevec); |
669 | mempool_free(p, nfs_wdata_mempool); |
670 | } |
671 | |
672 | -void nfs_writedata_release(void *data) |
673 | +static void nfs_writedata_release(struct nfs_write_data *wdata) |
674 | { |
675 | - struct nfs_write_data *wdata = data; |
676 | - |
677 | put_nfs_open_context(wdata->args.context); |
678 | nfs_writedata_free(wdata); |
679 | } |
680 | diff --git a/fs/proc/base.c b/fs/proc/base.c |
681 | index a488f61..76f9ffc 100644 |
682 | --- a/fs/proc/base.c |
683 | +++ b/fs/proc/base.c |
684 | @@ -240,22 +240,19 @@ static int check_mem_permission(struct task_struct *task) |
685 | struct mm_struct *mm_for_maps(struct task_struct *task) |
686 | { |
687 | struct mm_struct *mm = get_task_mm(task); |
688 | - if (!mm) |
689 | - return NULL; |
690 | - down_read(&mm->mmap_sem); |
691 | - task_lock(task); |
692 | - if (task->mm != mm) |
693 | - goto out; |
694 | - if (task->mm != current->mm && |
695 | - __ptrace_may_access(task, PTRACE_MODE_READ) < 0) |
696 | - goto out; |
697 | - task_unlock(task); |
698 | + |
699 | + if (mm && mm != current->mm) { |
700 | + /* |
701 | + * task->mm can be changed before security check, |
702 | + * in that case we must notice the change after. |
703 | + */ |
704 | + if (!ptrace_may_access(task, PTRACE_MODE_READ) || |
705 | + mm != task->mm) { |
706 | + mmput(mm); |
707 | + mm = NULL; |
708 | + } |
709 | + } |
710 | return mm; |
711 | -out: |
712 | - task_unlock(task); |
713 | - up_read(&mm->mmap_sem); |
714 | - mmput(mm); |
715 | - return NULL; |
716 | } |
717 | |
718 | static int proc_pid_cmdline(struct task_struct *task, char * buffer) |
719 | diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c |
720 | index c7f64a9..d8be92a 100644 |
721 | --- a/fs/proc/task_mmu.c |
722 | +++ b/fs/proc/task_mmu.c |
723 | @@ -119,6 +119,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) |
724 | mm = mm_for_maps(priv->task); |
725 | if (!mm) |
726 | return NULL; |
727 | + down_read(&mm->mmap_sem); |
728 | |
729 | tail_vma = get_gate_vma(priv->task); |
730 | priv->tail_vma = tail_vma; |
731 | diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c |
732 | index 5d84e71..737d219 100644 |
733 | --- a/fs/proc/task_nommu.c |
734 | +++ b/fs/proc/task_nommu.c |
735 | @@ -137,6 +137,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) |
736 | priv->task = NULL; |
737 | return NULL; |
738 | } |
739 | + down_read(&mm->mmap_sem); |
740 | |
741 | /* start from the Nth VMA */ |
742 | for (vml = mm->context.vmlist; vml; vml = vml->next) |
743 | diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c |
744 | index aedaeba..6def64c 100644 |
745 | --- a/fs/sysfs/dir.c |
746 | +++ b/fs/sysfs/dir.c |
747 | @@ -914,8 +914,10 @@ again: |
748 | /* Remove from old parent's list and insert into new parent's list. */ |
749 | sysfs_unlink_sibling(sd); |
750 | sysfs_get(new_parent_sd); |
751 | + drop_nlink(old_parent->d_inode); |
752 | sysfs_put(sd->s_parent); |
753 | sd->s_parent = new_parent_sd; |
754 | + inc_nlink(new_parent->d_inode); |
755 | sysfs_link_sibling(sd); |
756 | |
757 | out_unlock: |
758 | diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h |
759 | index 1f6fd4f..9c5d646 100644 |
760 | --- a/include/asm-parisc/tlbflush.h |
761 | +++ b/include/asm-parisc/tlbflush.h |
762 | @@ -12,14 +12,12 @@ |
763 | * N class systems, only one PxTLB inter processor broadcast can be |
764 | * active at any one time on the Merced bus. This tlb purge |
765 | * synchronisation is fairly lightweight and harmless so we activate |
766 | - * it on all SMP systems not just the N class. We also need to have |
767 | - * preemption disabled on uniprocessor machines, and spin_lock does that |
768 | - * nicely. |
769 | + * it on all systems not just the N class. |
770 | */ |
771 | extern spinlock_t pa_tlb_lock; |
772 | |
773 | -#define purge_tlb_start(x) spin_lock(&pa_tlb_lock) |
774 | -#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) |
775 | +#define purge_tlb_start(flags) spin_lock_irqsave(&pa_tlb_lock, flags) |
776 | +#define purge_tlb_end(flags) spin_unlock_irqrestore(&pa_tlb_lock, flags) |
777 | |
778 | extern void flush_tlb_all(void); |
779 | extern void flush_tlb_all_local(void *); |
780 | @@ -63,14 +61,15 @@ static inline void flush_tlb_mm(struct mm_struct *mm) |
781 | static inline void flush_tlb_page(struct vm_area_struct *vma, |
782 | unsigned long addr) |
783 | { |
784 | + unsigned long flags; |
785 | /* For one page, it's not worth testing the split_tlb variable */ |
786 | |
787 | mb(); |
788 | mtsp(vma->vm_mm->context,1); |
789 | - purge_tlb_start(); |
790 | + purge_tlb_start(flags); |
791 | pdtlb(addr); |
792 | pitlb(addr); |
793 | - purge_tlb_end(); |
794 | + purge_tlb_end(flags); |
795 | } |
796 | |
797 | void __flush_tlb_range(unsigned long sid, |
798 | diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h |
799 | index 424acb4..f57f2fb 100644 |
800 | --- a/include/asm-x86/irqflags.h |
801 | +++ b/include/asm-x86/irqflags.h |
802 | @@ -12,9 +12,15 @@ static inline unsigned long native_save_fl(void) |
803 | { |
804 | unsigned long flags; |
805 | |
806 | + /* |
807 | + * Note: this needs to be "=r" not "=rm", because we have the |
808 | + * stack offset from what gcc expects at the time the "pop" is |
809 | + * executed, and so a memory reference with respect to the stack |
810 | + * would end up using the wrong address. |
811 | + */ |
812 | asm volatile("# __raw_save_flags\n\t" |
813 | "pushf ; pop %0" |
814 | - : "=g" (flags) |
815 | + : "=r" (flags) |
816 | : /* no input */ |
817 | : "memory"); |
818 | |
819 | diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h |
820 | index 78a5922..0dee17c 100644 |
821 | --- a/include/linux/nfs_fs.h |
822 | +++ b/include/linux/nfs_fs.h |
823 | @@ -461,7 +461,6 @@ extern int nfs_writepages(struct address_space *, struct writeback_control *); |
824 | extern int nfs_flush_incompatible(struct file *file, struct page *page); |
825 | extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); |
826 | extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *); |
827 | -extern void nfs_writedata_release(void *); |
828 | |
829 | /* |
830 | * Try to write back everything synchronously (but check the |
831 | @@ -476,7 +475,6 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); |
832 | extern int nfs_commit_inode(struct inode *, int); |
833 | extern struct nfs_write_data *nfs_commitdata_alloc(void); |
834 | extern void nfs_commit_free(struct nfs_write_data *wdata); |
835 | -extern void nfs_commitdata_release(void *wdata); |
836 | #else |
837 | static inline int |
838 | nfs_commit_inode(struct inode *inode, int how) |
839 | @@ -495,6 +493,7 @@ nfs_have_writebacks(struct inode *inode) |
840 | * Allocate nfs_write_data structures |
841 | */ |
842 | extern struct nfs_write_data *nfs_writedata_alloc(unsigned int npages); |
843 | +extern void nfs_writedata_free(struct nfs_write_data *); |
844 | |
845 | /* |
846 | * linux/fs/nfs/read.c |
847 | @@ -503,12 +502,12 @@ extern int nfs_readpage(struct file *, struct page *); |
848 | extern int nfs_readpages(struct file *, struct address_space *, |
849 | struct list_head *, unsigned); |
850 | extern int nfs_readpage_result(struct rpc_task *, struct nfs_read_data *); |
851 | -extern void nfs_readdata_release(void *data); |
852 | |
853 | /* |
854 | * Allocate nfs_read_data structures |
855 | */ |
856 | extern struct nfs_read_data *nfs_readdata_alloc(unsigned int npages); |
857 | +extern void nfs_readdata_free(struct nfs_read_data *); |
858 | |
859 | /* |
860 | * linux/fs/nfs3proc.c |
861 | diff --git a/kernel/fork.c b/kernel/fork.c |
862 | index 843ce75..fcbd28c 100644 |
863 | --- a/kernel/fork.c |
864 | +++ b/kernel/fork.c |
865 | @@ -536,18 +536,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) |
866 | * the value intact in a core dump, and to save the unnecessary |
867 | * trouble otherwise. Userland only wants this done for a sys_exit. |
868 | */ |
869 | - if (tsk->clear_child_tid |
870 | - && !(tsk->flags & PF_SIGNALED) |
871 | - && atomic_read(&mm->mm_users) > 1) { |
872 | - u32 __user * tidptr = tsk->clear_child_tid; |
873 | + if (tsk->clear_child_tid) { |
874 | + if (!(tsk->flags & PF_SIGNALED) && |
875 | + atomic_read(&mm->mm_users) > 1) { |
876 | + /* |
877 | + * We don't check the error code - if userspace has |
878 | + * not set up a proper pointer then tough luck. |
879 | + */ |
880 | + put_user(0, tsk->clear_child_tid); |
881 | + sys_futex(tsk->clear_child_tid, FUTEX_WAKE, |
882 | + 1, NULL, NULL, 0); |
883 | + } |
884 | tsk->clear_child_tid = NULL; |
885 | - |
886 | - /* |
887 | - * We don't check the error code - if userspace has |
888 | - * not set up a proper pointer then tough luck. |
889 | - */ |
890 | - put_user(0, tidptr); |
891 | - sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0); |
892 | } |
893 | } |
894 | |
895 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
896 | index 1ecbcf6..2885674 100644 |
897 | --- a/mm/hugetlb.c |
898 | +++ b/mm/hugetlb.c |
899 | @@ -2257,7 +2257,7 @@ void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed) |
900 | long chg = region_truncate(&inode->i_mapping->private_list, offset); |
901 | |
902 | spin_lock(&inode->i_lock); |
903 | - inode->i_blocks -= blocks_per_huge_page(h); |
904 | + inode->i_blocks -= (blocks_per_huge_page(h) * freed); |
905 | spin_unlock(&inode->i_lock); |
906 | |
907 | hugetlb_put_quota(inode->i_mapping, (chg - freed)); |
908 | diff --git a/mm/page_alloc.c b/mm/page_alloc.c |
909 | index 85799e8..c6ecf87 100644 |
910 | --- a/mm/page_alloc.c |
911 | +++ b/mm/page_alloc.c |
912 | @@ -846,7 +846,7 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order, |
913 | */ |
914 | static int rmqueue_bulk(struct zone *zone, unsigned int order, |
915 | unsigned long count, struct list_head *list, |
916 | - int migratetype) |
917 | + int migratetype, int cold) |
918 | { |
919 | int i; |
920 | |
921 | @@ -865,7 +865,10 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, |
922 | * merge IO requests if the physical pages are ordered |
923 | * properly. |
924 | */ |
925 | - list_add(&page->lru, list); |
926 | + if (likely(cold == 0)) |
927 | + list_add(&page->lru, list); |
928 | + else |
929 | + list_add_tail(&page->lru, list); |
930 | set_page_private(page, migratetype); |
931 | list = &page->lru; |
932 | } |
933 | @@ -1068,7 +1071,8 @@ again: |
934 | local_irq_save(flags); |
935 | if (!pcp->count) { |
936 | pcp->count = rmqueue_bulk(zone, 0, |
937 | - pcp->batch, &pcp->list, migratetype); |
938 | + pcp->batch, &pcp->list, |
939 | + migratetype, cold); |
940 | if (unlikely(!pcp->count)) |
941 | goto failed; |
942 | } |
943 | @@ -1087,7 +1091,8 @@ again: |
944 | /* Allocate more to the pcp list if necessary */ |
945 | if (unlikely(&page->lru == &pcp->list)) { |
946 | pcp->count += rmqueue_bulk(zone, 0, |
947 | - pcp->batch, &pcp->list, migratetype); |
948 | + pcp->batch, &pcp->list, |
949 | + migratetype, cold); |
950 | page = list_entry(pcp->list.next, struct page, lru); |
951 | } |
952 | |
953 | diff --git a/net/socket.c b/net/socket.c |
954 | index 3e2859c..058d965 100644 |
955 | --- a/net/socket.c |
956 | +++ b/net/socket.c |
957 | @@ -695,7 +695,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, |
958 | if (more) |
959 | flags |= MSG_MORE; |
960 | |
961 | - return sock->ops->sendpage(sock, page, offset, size, flags); |
962 | + return kernel_sendpage(sock, page, offset, size, flags); |
963 | } |
964 | |
965 | static ssize_t sock_splice_read(struct file *file, loff_t *ppos, |