From: Greg Kroah-Hartman Date: Wed, 29 Apr 2009 01:50:30 +0000 (-0700) Subject: lots of .28 patches X-Git-Tag: v2.6.27.22~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=359b2fed80cba82bd5f1a2b53855eed2145d21e7;p=thirdparty%2Fkernel%2Fstable-queue.git lots of .28 patches --- diff --git a/queue-2.6.28/0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch b/queue-2.6.28/0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch new file mode 100644 index 00000000000..89d41bb7d9d --- /dev/null +++ b/queue-2.6.28/0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch @@ -0,0 +1,42 @@ +From 97ecdadc284e820931f27c6345b0ff8b85792346 Mon Sep 17 00:00:00 2001 +From: Etienne Basset +Date: Tue, 31 Mar 2009 23:54:11 +0200 +Subject: security/smack: fix oops when setting a size 0 SMACK64 xattr + +From: Etienne Basset + +upstream commit: 4303154e86597885bc3cbc178a48ccbc8213875f + +this patch fix an oops in smack when setting a size 0 SMACK64 xattr eg +attr -S -s SMACK64 -V '' somefile +This oops because smk_import_entry treats a 0 length as SMK_MAXLEN + +Signed-off-by: Etienne Basset +Reviewed-by: James Morris +Acked-by: Casey Schaufler +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + security/smack/smack_lsm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -604,6 +604,8 @@ static int smack_inode_setxattr(struct d + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + if (!capable(CAP_MAC_ADMIN)) + rc = -EPERM; ++ if (size == 0) ++ rc = -EINVAL; + } else + rc = cap_inode_setxattr(dentry, name, value, size, flags); + +@@ -1360,7 +1362,7 @@ static int smack_inode_setsecurity(struc + struct socket *sock; + int rc = 0; + +- if (value == NULL || size > SMK_LABELLEN) ++ if (value == NULL || size > SMK_LABELLEN || size == 0) + return -EACCES; + + sp = smk_import(value, size); diff --git a/queue-2.6.28/0008-USB-EHCI-add-software-retry-for-transaction-errors.patch b/queue-2.6.28/0008-USB-EHCI-add-software-retry-for-transaction-errors.patch index 541ab48af2b..b2a26f75184 100644 --- a/queue-2.6.28/0008-USB-EHCI-add-software-retry-for-transaction-errors.patch +++ b/queue-2.6.28/0008-USB-EHCI-add-software-retry-for-transaction-errors.patch @@ -3,6 +3,8 @@ From: Alan Stern Date: Thu, 26 Mar 2009 18:25:05 +0000 Subject: USB: EHCI: add software retry for transaction errors +From: Alan Stern + upstream commit: a2c2706e1043c17139c2dafd171c4a5cf008ef7e This patch (as1204) adds a software retry mechanism to ehci-hcd. It diff --git a/queue-2.6.28/0009-USB-fix-USB_STORAGE_CYPRESS_ATACB.patch b/queue-2.6.28/0009-USB-fix-USB_STORAGE_CYPRESS_ATACB.patch index cceda456996..23cac33d3d1 100644 --- a/queue-2.6.28/0009-USB-fix-USB_STORAGE_CYPRESS_ATACB.patch +++ b/queue-2.6.28/0009-USB-fix-USB_STORAGE_CYPRESS_ATACB.patch @@ -3,6 +3,8 @@ From: Boaz Harrosh Date: Thu, 26 Mar 2009 18:25:07 +0000 Subject: USB: fix USB_STORAGE_CYPRESS_ATACB +From: Boaz Harrosh + upstream commit: 1f4159c1620f74377e26d8a569d10ca5907ef475 commit 64a87b24: [SCSI] Let scsi_cmnd->cmnd use request->cmd buffer diff --git a/queue-2.6.28/0010-USB-usb-storage-increase-max_sectors-for-tape-driv.patch b/queue-2.6.28/0010-USB-usb-storage-increase-max_sectors-for-tape-driv.patch index 69930b904d3..05b18683367 100644 --- a/queue-2.6.28/0010-USB-usb-storage-increase-max_sectors-for-tape-driv.patch +++ b/queue-2.6.28/0010-USB-usb-storage-increase-max_sectors-for-tape-driv.patch @@ -3,6 +3,8 @@ From: Alan Stern Date: Thu, 26 Mar 2009 18:25:09 +0000 Subject: USB: usb-storage: increase max_sectors for tape drives +From: Alan Stern +' upstream commit: 5c16034d73da2c1b663aa25dedadbc533b3d811c This patch (as1203) increases the max_sector limit for USB tape diff --git a/queue-2.6.28/0011-USB-gadget-fix-rndis-regression.patch b/queue-2.6.28/0011-USB-gadget-fix-rndis-regression.patch index a84663eae00..1b7ab0c1b61 100644 --- a/queue-2.6.28/0011-USB-gadget-fix-rndis-regression.patch +++ b/queue-2.6.28/0011-USB-gadget-fix-rndis-regression.patch @@ -3,6 +3,8 @@ From: David Brownell Date: Thu, 26 Mar 2009 18:25:12 +0000 Subject: USB: gadget: fix rndis regression +From: David Brownell + upstream commit: 090b90118207e786d2990310d063fda5d52cce6e Restore some code that was wrongly dropped from the RNDIS diff --git a/queue-2.6.28/0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch b/queue-2.6.28/0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch new file mode 100644 index 00000000000..5b70bdbefd8 --- /dev/null +++ b/queue-2.6.28/0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch @@ -0,0 +1,45 @@ +From 32626208c6548358e28b0857ad030b8a3fa12d86 Mon Sep 17 00:00:00 2001 +From: Michael K. Johnson +Date: Wed, 1 Apr 2009 20:40:02 +0000 +Subject: x86, setup: mark %esi as clobbered in E820 BIOS call + +From: Michael K. Johnson + +upstream commit: 01522df346f846906eaf6ca57148641476209909 + +Jordan Hargrave diagnosed a BIOS clobbering %esi in the E820 call. +That particular BIOS has been fixed, but there is a possibility that +this is responsible for other occasional reports of early boot +failure, and it does not hurt to add %esi to the clobbers. + +-stable candidate patch. + +Cc: Justin Forbes +Signed-off-by: Michael K Johnson +Signed-off-by: H. Peter Anvin +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/boot/memory.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/arch/x86/boot/memory.c ++++ b/arch/x86/boot/memory.c +@@ -27,13 +27,14 @@ static int detect_memory_e820(void) + do { + size = sizeof(struct e820entry); + +- /* Important: %edx is clobbered by some BIOSes, +- so it must be either used for the error output ++ /* Important: %edx and %esi are clobbered by some BIOSes, ++ so they must be either used for the error output + or explicitly marked clobbered. */ + asm("int $0x15; setc %0" + : "=d" (err), "+b" (next), "=a" (id), "+c" (size), + "=m" (*desc) +- : "D" (desc), "d" (SMAP), "a" (0xe820)); ++ : "D" (desc), "d" (SMAP), "a" (0xe820) ++ : "esi"); + + /* BIOSes which terminate the chain with CF = 1 as opposed + to %ebx = 0 don't always report the SMAP signature on diff --git a/queue-2.6.28/0012-USB-add-quirk-to-avoid-config-and-interface-strings.patch b/queue-2.6.28/0012-USB-add-quirk-to-avoid-config-and-interface-strings.patch index fbac1d6d458..243077cace3 100644 --- a/queue-2.6.28/0012-USB-add-quirk-to-avoid-config-and-interface-strings.patch +++ b/queue-2.6.28/0012-USB-add-quirk-to-avoid-config-and-interface-strings.patch @@ -3,6 +3,8 @@ From: Alan Stern Date: Thu, 26 Mar 2009 18:25:19 +0000 Subject: USB: add quirk to avoid config and interface strings +From: Alan Stern + upstream commit: 1662e3a7f076e51e3073faf9ce77157b529c475b Apparently the Configuration and Interface strings aren't used as diff --git a/queue-2.6.28/0013-dock-fix-dereference-after-kfree.patch b/queue-2.6.28/0013-dock-fix-dereference-after-kfree.patch new file mode 100644 index 00000000000..114175b26d3 --- /dev/null +++ b/queue-2.6.28/0013-dock-fix-dereference-after-kfree.patch @@ -0,0 +1,36 @@ +From 538c7aac35f4282d7674c473f099b323b1e020dd Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 6 Apr 2009 23:56:46 -0400 +Subject: dock: fix dereference after kfree() + +From: Dan Carpenter + +upstream commit: f240729832dff3785104d950dad2d3ced4387f6d + +dock_remove() calls kfree() on dock_station so we should use +list_for_each_entry_safe() to avoid dereferencing freed memory. + +Found by smatch (http://repo.or.cz/w/smatch.git/). Compile tested. + +Signed-off-by: Dan Carpenter +Signed-off-by: Len Brown +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/dock.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/acpi/dock.c ++++ b/drivers/acpi/dock.c +@@ -1146,9 +1146,10 @@ static int __init dock_init(void) + static void __exit dock_exit(void) + { + struct dock_station *dock_station; ++ struct dock_station *tmp; + + unregister_acpi_bus_notifier(&dock_acpi_notifier); +- list_for_each_entry(dock_station, &dock_stations, sibiling) ++ list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling) + dock_remove(dock_station); + } + diff --git a/queue-2.6.28/0016-cifs-fix-buffer-format-byte-on-NT-Rename-hardlink.patch b/queue-2.6.28/0016-cifs-fix-buffer-format-byte-on-NT-Rename-hardlink.patch index a0a4ae56b27..8c6823c15e5 100644 --- a/queue-2.6.28/0016-cifs-fix-buffer-format-byte-on-NT-Rename-hardlink.patch +++ b/queue-2.6.28/0016-cifs-fix-buffer-format-byte-on-NT-Rename-hardlink.patch @@ -3,6 +3,8 @@ From: Jeff Layton Date: Thu, 26 Mar 2009 23:05:21 +0000 Subject: cifs: fix buffer format byte on NT Rename/hardlink +From: Jeff Layton + upstream commit: fcc7c09d94be7b75c9ea2beb22d0fae191c6b4b9 Discovered at Connnectathon 2009... @@ -12,10 +14,10 @@ The buffer format byte and the pad are transposed in NT_RENAME calls fact, but NetApp filers throw back an error due to this problem. This patch fixes it. -CC: Stable Signed-off-by: Jeff Layton Signed-off-by: Steve French Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman --- fs/cifs/cifssmb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/queue-2.6.28/0019-b43-fix-b43_plcp_get_bitrate_idx_ofdm-return-type.patch b/queue-2.6.28/0019-b43-fix-b43_plcp_get_bitrate_idx_ofdm-return-type.patch index 5d24ec46884..6fa57ee3f2b 100644 --- a/queue-2.6.28/0019-b43-fix-b43_plcp_get_bitrate_idx_ofdm-return-type.patch +++ b/queue-2.6.28/0019-b43-fix-b43_plcp_get_bitrate_idx_ofdm-return-type.patch @@ -3,6 +3,8 @@ From: Lorenzo Nava Date: Sat, 28 Mar 2009 01:45:06 +0000 Subject: b43: fix b43_plcp_get_bitrate_idx_ofdm return type +From: Lorenzo Nava + upstream commit: a3c0b87c4f21911fb7185902dd13f0e3cd7f33f7 This patch fixes the return type of b43_plcp_get_bitrate_idx_ofdm. If @@ -10,11 +12,11 @@ the plcp contains an error, the function return value is 255 instead of -1, and the packet was not dropped. This causes a warning in __ieee80211_rx function because rate idx is out of range. -Cc: stable@kernel.org Signed-off-by: Lorenzo Nava Signed-off-by: Michael Buesch Signed-off-by: John W. Linville Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/b43/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queue-2.6.28/0022-CIFS-Fix-memory-overwrite-when-saving-nativeFileSys.patch b/queue-2.6.28/0022-CIFS-Fix-memory-overwrite-when-saving-nativeFileSys.patch index d436e33f07e..cc6fe1516c4 100644 --- a/queue-2.6.28/0022-CIFS-Fix-memory-overwrite-when-saving-nativeFileSys.patch +++ b/queue-2.6.28/0022-CIFS-Fix-memory-overwrite-when-saving-nativeFileSys.patch @@ -3,6 +3,8 @@ From: Steve French Date: Thu, 26 Mar 2009 23:05:15 +0000 Subject: CIFS: Fix memory overwrite when saving nativeFileSystem field during mount +From: Steve French + upstream commit: b363b3304bcf68c4541683b2eff70b29f0446a5b CIFS can allocate a few bytes to little for the nativeFileSystem field @@ -11,10 +13,10 @@ in a "Redzone overwritten" message to be logged. Signed-off-by: Sridhar Vinay Acked-by: Shirish Pargaonkar -CC: Stable Signed-off-by: Steve French [chrisw: minor backport to CHANGES file] Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman --- fs/cifs/CHANGES | 3 +++ fs/cifs/connect.c | 2 +- diff --git a/queue-2.6.28/0024-r8169-Reset-IntrStatus-after-chip-reset.patch b/queue-2.6.28/0024-r8169-Reset-IntrStatus-after-chip-reset.patch new file mode 100644 index 00000000000..346c2eac1d2 --- /dev/null +++ b/queue-2.6.28/0024-r8169-Reset-IntrStatus-after-chip-reset.patch @@ -0,0 +1,54 @@ +From 98bf3a0cf25dbd438500d9c9fcf583d7a2b97825 Mon Sep 17 00:00:00 2001 +From: Francois Romieu +Date: Mon, 6 Apr 2009 23:35:13 +0200 +Subject: r8169: Reset IntrStatus after chip reset + +From: Francois Romieu + +upstream commit: d78ad8cbfe73ad568de38814a75e9c92ad0a907c + +Original comment (Karsten): +On a MSI MS-6702E mainboard, when in rtl8169_init_one() for the first time +after BIOS has run, IntrStatus reads 5 after chip has been reset. +IntrStatus should equal 0 there, so patch changes IntrStatus reset to happen +after chip reset instead of before. + +Remark (Francois): +Assuming that the loglevel of the driver is increased above NETIF_MSG_INTR, +the bug reveals itself with a typical "interrupt 0025 in poll" message +at startup. In retrospect, the message should had been read as an hint of +an unexpected hardware state several months ago :o( + +Fixes (at least part of) https://bugzilla.redhat.com/show_bug.cgi?id=460747 + +Signed-off-by: Karsten Wiese +Signed-off-by: Francois Romieu +Tested-by: Josep +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -2026,8 +2026,7 @@ rtl8169_init_one(struct pci_dev *pdev, c + if (!tp->pcie_cap && netif_msg_probe(tp)) + dev_info(&pdev->dev, "no PCI Express capability\n"); + +- /* Unneeded ? Don't mess with Mrs. Murphy. */ +- rtl8169_irq_mask_and_ack(ioaddr); ++ RTL_W16(IntrMask, 0x0000); + + /* Soft reset the chip. */ + RTL_W8(ChipCmd, CmdReset); +@@ -2039,6 +2038,8 @@ rtl8169_init_one(struct pci_dev *pdev, c + msleep_interruptible(1); + } + ++ RTL_W16(IntrStatus, 0xffff); ++ + /* Identify chip attached to board */ + rtl8169_get_mac_version(tp, ioaddr); + diff --git a/queue-2.6.28/0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch b/queue-2.6.28/0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch new file mode 100644 index 00000000000..c5564e4b873 --- /dev/null +++ b/queue-2.6.28/0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch @@ -0,0 +1,58 @@ +From ee21b9af3d0b0b3261daba2f669e7e9aeda1eaa2 Mon Sep 17 00:00:00 2001 +From: Lee Schermerhorn +Date: Fri, 3 Apr 2009 04:35:10 +0000 +Subject: mm: define a UNIQUE value for AS_UNEVICTABLE flag + +From: Lee Schermerhorn + +upstream commit: 9a896c9a48ac6704c0ce8ee081b836644d0afe40 + +A new "address_space flag"--AS_MM_ALL_LOCKS--was defined to use the next +available AS flag while the Unevictable LRU was under development. The +Unevictable LRU was using the same flag and "no one" noticed. Current +mainline, since 2.6.28, has same value for two symbolic flag names. + +So, define a unique flag value for AS_UNEVICTABLE--up close to the other +flags, [at the cost of an additional #ifdef] so we'll notice next time. +Note that #ifdef is not actually required, if we don't mind having the +unused flag value defined. + +Replace #defines with an enum. + +Signed-off-by: Lee Schermerhorn +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/pagemap.h | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/include/linux/pagemap.h ++++ b/include/linux/pagemap.h +@@ -18,9 +18,14 @@ + * Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page + * allocation mode flags. + */ +-#define AS_EIO (__GFP_BITS_SHIFT + 0) /* IO error on async write */ +-#define AS_ENOSPC (__GFP_BITS_SHIFT + 1) /* ENOSPC on async write */ +-#define AS_MM_ALL_LOCKS (__GFP_BITS_SHIFT + 2) /* under mm_take_all_locks() */ ++enum mapping_flags { ++ AS_EIO = __GFP_BITS_SHIFT + 0, /* IO error on async write */ ++ AS_ENOSPC = __GFP_BITS_SHIFT + 1, /* ENOSPC on async write */ ++ AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */ ++#ifdef CONFIG_UNEVICTABLE_LRU ++ AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */ ++#endif ++}; + + static inline void mapping_set_error(struct address_space *mapping, int error) + { +@@ -33,7 +38,6 @@ static inline void mapping_set_error(str + } + + #ifdef CONFIG_UNEVICTABLE_LRU +-#define AS_UNEVICTABLE (__GFP_BITS_SHIFT + 2) /* e.g., ramdisk, SHM_LOCK */ + + static inline void mapping_set_unevictable(struct address_space *mapping) + { diff --git a/queue-2.6.28/0031-mm-do_xip_mapping_read-fix-length-calculation.patch b/queue-2.6.28/0031-mm-do_xip_mapping_read-fix-length-calculation.patch new file mode 100644 index 00000000000..cf6cdec2971 --- /dev/null +++ b/queue-2.6.28/0031-mm-do_xip_mapping_read-fix-length-calculation.patch @@ -0,0 +1,66 @@ +From d4a0936d21ddba01f85daf686625f0004b896aae Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Fri, 3 Apr 2009 04:35:12 +0000 +Subject: mm: do_xip_mapping_read: fix length calculation + +From: Martin Schwidefsky + +upstream commit: 58984ce21d315b70df1a43644df7416ea7c9bfd8 + +The calculation of the value nr in do_xip_mapping_read is incorrect. If +the copy required more than one iteration in the do while loop the copies +variable will be non-zero. The maximum length that may be passed to the +call to copy_to_user(buf+copied, xip_mem+offset, nr) is len-copied but the +check only compares against (nr > len). + +This bug is the cause for the heap corruption Carsten has been chasing +for so long: + + *** glibc detected *** /bin/bash: free(): invalid next size (normal): 0x00000000800e39f0 *** + ======= Backtrace: ========= +/lib64/libc.so.6[0x200000b9b44] +/lib64/libc.so.6(cfree+0x8e)[0x200000bdade] +/bin/bash(free_buffered_stream+0x32)[0x80050e4e] +/bin/bash(close_buffered_stream+0x1c)[0x80050ea4] +/bin/bash(unset_bash_input+0x2a)[0x8001c366] +/bin/bash(make_child+0x1d4)[0x8004115c] +/bin/bash[0x8002fc3c] +/bin/bash(execute_command_internal+0x656)[0x8003048e] +/bin/bash(execute_command+0x5e)[0x80031e1e] +/bin/bash(execute_command_internal+0x79a)[0x800305d2] +/bin/bash(execute_command+0x5e)[0x80031e1e] +/bin/bash(reader_loop+0x270)[0x8001efe0] +/bin/bash(main+0x1328)[0x8001e960] +/lib64/libc.so.6(__libc_start_main+0x100)[0x200000592a8] +/bin/bash(clearerr+0x5e)[0x8001c092] + +With this bug fix the commit 0e4a9b59282914fe057ab17027f55123964bc2e2 +"ext2/xip: refuse to change xip flag during remount with busy inodes" can +be removed again. + +Cc: Carsten Otte +Cc: Nick Piggin +Cc: Jared Hulbert +Signed-off-by: Martin Schwidefsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman + +--- + mm/filemap_xip.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/mm/filemap_xip.c ++++ b/mm/filemap_xip.c +@@ -89,8 +89,8 @@ do_xip_mapping_read(struct address_space + } + } + nr = nr - offset; +- if (nr > len) +- nr = len; ++ if (nr > len - copied) ++ nr = len - copied; + + error = mapping->a_ops->get_xip_mem(mapping, index, 0, + &xip_mem, &xip_pfn); diff --git a/queue-2.6.28/0032-Add-a-missing-unlock_kernel-in-raw_open.patch b/queue-2.6.28/0032-Add-a-missing-unlock_kernel-in-raw_open.patch index a13bddfd9d7..816c7c7b591 100644 --- a/queue-2.6.28/0032-Add-a-missing-unlock_kernel-in-raw_open.patch +++ b/queue-2.6.28/0032-Add-a-missing-unlock_kernel-in-raw_open.patch @@ -3,12 +3,14 @@ From: Dan Carpenter Date: Mon, 30 Mar 2009 18:50:16 +0000 Subject: Add a missing unlock_kernel() in raw_open() +From: Dan Carpenter + upstream commit: 996ff68d8b358885c1de82a45517c607999947c7 -Cc: stable@kernel.org Signed-off-by: Dan Carpenter Signed-off-by: Jonathan Corbet Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman --- drivers/char/raw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/queue-2.6.28/0033-x86-PAT-PCI-Change-vma-prot-in-pci_mmap-to-reflec.patch b/queue-2.6.28/0033-x86-PAT-PCI-Change-vma-prot-in-pci_mmap-to-reflec.patch index 55575cb96b4..190a9d4181d 100644 --- a/queue-2.6.28/0033-x86-PAT-PCI-Change-vma-prot-in-pci_mmap-to-reflec.patch +++ b/queue-2.6.28/0033-x86-PAT-PCI-Change-vma-prot-in-pci_mmap-to-reflec.patch @@ -3,6 +3,8 @@ From: Pallipadi, Venkatesh Date: Mon, 30 Mar 2009 18:50:19 +0000 Subject: x86, PAT, PCI: Change vma prot in pci_mmap to reflect inherited prot +From: Venkatesh Pallipadi + upstream commit: 9cdec049389ce2c324fd1ec508a71528a27d4a07 While looking at the issue in the thread: @@ -22,10 +24,10 @@ Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Cc: Jesse Barnes Cc: Dave Airlie -Cc: LKML-Reference: <20090323190720.GA16831@linux-os.sc.intel.com> Signed-off-by: Ingo Molnar Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman --- arch/x86/pci/i386.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/queue-2.6.28/0034-vfs-skip-I_CLEAR-state-inodes.patch b/queue-2.6.28/0034-vfs-skip-I_CLEAR-state-inodes.patch new file mode 100644 index 00000000000..b26082ffc78 --- /dev/null +++ b/queue-2.6.28/0034-vfs-skip-I_CLEAR-state-inodes.patch @@ -0,0 +1,94 @@ +From 187ab6618c3afae07d5ca0727966ea461e5d07a7 Mon Sep 17 00:00:00 2001 +From: Wu Fengguang +Date: Fri, 3 Apr 2009 04:35:14 +0000 +Subject: vfs: skip I_CLEAR state inodes + +From: Wu Fengguang + +upstream commit: b6fac63cc1f52ec27f29fe6c6c8494a2ffac33fd + +clear_inode() will switch inode state from I_FREEING to I_CLEAR, and do so +_outside_ of inode_lock. So any I_FREEING testing is incomplete without a +coupled testing of I_CLEAR. + +So add I_CLEAR tests to drop_pagecache_sb(), generic_sync_sb_inodes() and +add_dquot_ref(). + +Masayoshi MIZUMA discovered the bug in drop_pagecache_sb() and Jan Kara +reminds fixing the other two cases. + +Masayoshi MIZUMA has a nice panic flow: + +===================================================================== + [process A] | [process B] + | | + | prune_icache() | drop_pagecache() + | spin_lock(&inode_lock) | drop_pagecache_sb() + | inode->i_state |= I_FREEING; | | + | spin_unlock(&inode_lock) | V + | | | spin_lock(&inode_lock) + | V | | + | dispose_list() | | + | list_del() | | + | clear_inode() | | + | inode->i_state = I_CLEAR | | + | | | V + | | | if (inode->i_state & (I_FREEING|I_WILL_FREE)) + | | | continue; <==== NOT MATCH + | | | + | | | (DANGER from here on! Accessing disposing inode!) + | | | + | | | __iget() + | | | list_move() <===== PANIC on poisoned list !! + V V | +(time) +===================================================================== + +Reported-by: Masayoshi MIZUMA +Reviewed-by: Jan Kara +Signed-off-by: Wu Fengguang +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +[chrisw: backport to 2.6.29] +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + fs/dquot.c | 2 +- + fs/drop_caches.c | 2 +- + fs/fs-writeback.c | 3 ++- + 3 files changed, 4 insertions(+), 3 deletions(-) + +--- a/fs/dquot.c ++++ b/fs/dquot.c +@@ -724,7 +724,7 @@ static void add_dquot_ref(struct super_b + continue; + if (!dqinit_needed(inode, type)) + continue; +- if (inode->i_state & (I_FREEING|I_WILL_FREE)) ++ if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) + continue; + + __iget(inode); +--- a/fs/drop_caches.c ++++ b/fs/drop_caches.c +@@ -18,7 +18,7 @@ static void drop_pagecache_sb(struct sup + + spin_lock(&inode_lock); + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { +- if (inode->i_state & (I_FREEING|I_WILL_FREE)) ++ if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) + continue; + if (inode->i_mapping->nrpages == 0) + continue; +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -538,7 +538,8 @@ void generic_sync_sb_inodes(struct super + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { + struct address_space *mapping; + +- if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ++ if (inode->i_state & ++ (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) + continue; + mapping = inode->i_mapping; + if (mapping->nrpages == 0) diff --git a/queue-2.6.28/0037-x86-mtrr-don-t-modify-RdDram-WrDram-bits-of-fixed.patch b/queue-2.6.28/0037-x86-mtrr-don-t-modify-RdDram-WrDram-bits-of-fixed.patch index e919ec0959a..0c193564355 100644 --- a/queue-2.6.28/0037-x86-mtrr-don-t-modify-RdDram-WrDram-bits-of-fixed.patch +++ b/queue-2.6.28/0037-x86-mtrr-don-t-modify-RdDram-WrDram-bits-of-fixed.patch @@ -3,6 +3,8 @@ From: Andreas Herrmann Date: Mon, 30 Mar 2009 18:50:32 +0000 Subject: x86: mtrr: don't modify RdDram/WrDram bits of fixed MTRRs +From: Andreas Herrmann + upstream commit: 3ff42da5048649503e343a32be37b14a6a4e8aaf Impact: bug fix + BIOS workaround @@ -63,9 +65,9 @@ Signed-off-by: Andreas Herrmann Cc: trenn@suse.de Cc: Yinghai Lu LKML-Reference: <20090312163937.GH20716@alberich.amd.com> -Cc: Signed-off-by: Ingo Molnar Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/mtrr/generic.c | 51 +++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/queue-2.6.28/0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch b/queue-2.6.28/0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch new file mode 100644 index 00000000000..425ff6e240c --- /dev/null +++ b/queue-2.6.28/0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch @@ -0,0 +1,68 @@ +From 33d06566b593703a972da232d08b6a12176f1854 Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Fri, 27 Mar 2009 00:28:21 -0700 +Subject: af_rose/x25: Sanity check the maximum user frame size + +From: Alan Cox + +upstream commit: 83e0bbcbe2145f160fbaa109b0439dae7f4a38a9 + +CVE-2009-0795. + +Otherwise we can wrap the sizes and end up sending garbage. + +Closes #10423 + +Signed-off-by: Alan Cox +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + net/netrom/af_netrom.c | 6 +++++- + net/rose/af_rose.c | 4 ++++ + net/x25/af_x25.c | 6 ++++++ + 3 files changed, 15 insertions(+), 1 deletion(-) + +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -1082,7 +1082,11 @@ static int nr_sendmsg(struct kiocb *iocb + + SOCK_DEBUG(sk, "NET/ROM: sendto: Addresses built.\n"); + +- /* Build a packet */ ++ /* Build a packet - the conventional user limit is 236 bytes. We can ++ do ludicrously large NetROM frames but must not overflow */ ++ if (len > 65536) ++ return -EMSGSIZE; ++ + SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n"); + size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN; + +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -1124,6 +1124,10 @@ static int rose_sendmsg(struct kiocb *io + + /* Build a packet */ + SOCK_DEBUG(sk, "ROSE: sendto: building packet.\n"); ++ /* Sanity check the packet size */ ++ if (len > 65535) ++ return -EMSGSIZE; ++ + size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN; + + if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL) +--- a/net/x25/af_x25.c ++++ b/net/x25/af_x25.c +@@ -1037,6 +1037,12 @@ static int x25_sendmsg(struct kiocb *ioc + sx25.sx25_addr = x25->dest_addr; + } + ++ /* Sanity check the packet size */ ++ if (len > 65535) { ++ rc = -EMSGSIZE; ++ goto out; ++ } ++ + SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n"); + + /* Build a packet */ diff --git a/queue-2.6.28/0044-net-netrom-Fix-socket-locking.patch b/queue-2.6.28/0044-net-netrom-Fix-socket-locking.patch new file mode 100644 index 00000000000..6dbbd1e55bd --- /dev/null +++ b/queue-2.6.28/0044-net-netrom-Fix-socket-locking.patch @@ -0,0 +1,37 @@ +From df5b6025d1a9e2e61dde1fd28257082751264c07 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 22 Apr 2009 00:49:51 -0700 +Subject: net/netrom: Fix socket locking + +From: Jean Delvare + +upstream commit: cc29c70dd581f85ee7a3e7980fb031f90b90a2ab + +Patch "af_rose/x25: Sanity check the maximum user frame size" +(commit 83e0bbcbe2145f160fbaa109b0439dae7f4a38a9) from Alan Cox got +locking wrong. If we bail out due to user frame size being too large, +we must unlock the socket beforehand. + +Signed-off-by: Jean Delvare +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + net/netrom/af_netrom.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -1084,8 +1084,10 @@ static int nr_sendmsg(struct kiocb *iocb + + /* Build a packet - the conventional user limit is 236 bytes. We can + do ludicrously large NetROM frames but must not overflow */ +- if (len > 65536) +- return -EMSGSIZE; ++ if (len > 65536) { ++ err = -EMSGSIZE; ++ goto out; ++ } + + SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n"); + size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN; diff --git a/queue-2.6.28/0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch b/queue-2.6.28/0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch new file mode 100644 index 00000000000..9811f2eb2bd --- /dev/null +++ b/queue-2.6.28/0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch @@ -0,0 +1,70 @@ +From 6bc1b5deb47f0fc3d697abd2fcd417618cf07e3f Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Mon, 6 Apr 2009 17:31:29 +0200 +Subject: netfilter: {ip, ip6, arp}_tables: fix incorrect loop detection + +From: Patrick McHardy + +upstream commit: 1f9352ae2253a97b07b34dcf16ffa3b4ca12c558 + +Commit e1b4b9f ([NETFILTER]: {ip,ip6,arp}_tables: fix exponential worst-case +search for loops) introduced a regression in the loop detection algorithm, +causing sporadic incorrectly detected loops. + +When a chain has already been visited during the check, it is treated as +having a standard target containing a RETURN verdict directly at the +beginning in order to not check it again. The real target of the first +rule is then incorrectly treated as STANDARD target and checked not to +contain invalid verdicts. + +Fix by making sure the rule does actually contain a standard target. + +Based on patch by Francis Dupont +Signed-off-by: Patrick McHardy +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/netfilter/arp_tables.c | 4 +++- + net/ipv4/netfilter/ip_tables.c | 4 +++- + net/ipv6/netfilter/ip6_tables.c | 4 +++- + 3 files changed, 9 insertions(+), 3 deletions(-) + +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -374,7 +374,9 @@ static int mark_source_chains(struct xt_ + && unconditional(&e->arp)) || visited) { + unsigned int oldpos, size; + +- if (t->verdict < -NF_MAX_VERDICT - 1) { ++ if ((strcmp(t->target.u.user.name, ++ ARPT_STANDARD_TARGET) == 0) && ++ t->verdict < -NF_MAX_VERDICT - 1) { + duprintf("mark_source_chains: bad " + "negative verdict (%i)\n", + t->verdict); +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -500,7 +500,9 @@ mark_source_chains(struct xt_table_info + && unconditional(&e->ip)) || visited) { + unsigned int oldpos, size; + +- if (t->verdict < -NF_MAX_VERDICT - 1) { ++ if ((strcmp(t->target.u.user.name, ++ IPT_STANDARD_TARGET) == 0) && ++ t->verdict < -NF_MAX_VERDICT - 1) { + duprintf("mark_source_chains: bad " + "negative verdict (%i)\n", + t->verdict); +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -525,7 +525,9 @@ mark_source_chains(struct xt_table_info + && unconditional(&e->ipv6)) || visited) { + unsigned int oldpos, size; + +- if (t->verdict < -NF_MAX_VERDICT - 1) { ++ if ((strcmp(t->target.u.user.name, ++ IP6T_STANDARD_TARGET) == 0) && ++ t->verdict < -NF_MAX_VERDICT - 1) { + duprintf("mark_source_chains: bad " + "negative verdict (%i)\n", + t->verdict); diff --git a/queue-2.6.28/0049-splice-fix-deadlock-in-splicing-to-file.patch b/queue-2.6.28/0049-splice-fix-deadlock-in-splicing-to-file.patch new file mode 100644 index 00000000000..24e2d06ca9f --- /dev/null +++ b/queue-2.6.28/0049-splice-fix-deadlock-in-splicing-to-file.patch @@ -0,0 +1,117 @@ +From ed960ac61e12e298d1cdcd52b21b9ee07d36755c Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Tue, 7 Apr 2009 16:25:02 +0000 +Subject: splice: fix deadlock in splicing to file + +From: Miklos Szeredi + +upstream commit: 7bfac9ecf0585962fe13584f5cf526d8c8e76f17 + +There's a possible deadlock in generic_file_splice_write(), +splice_from_pipe() and ocfs2_file_splice_write(): + + - task A calls generic_file_splice_write() + - this calls inode_double_lock(), which locks i_mutex on both + pipe->inode and target inode + - ordering depends on inode pointers, can happen that pipe->inode is + locked first + - __splice_from_pipe() needs more data, calls pipe_wait() + - this releases lock on pipe->inode, goes to interruptible sleep + - task B calls generic_file_splice_write(), similarly to the first + - this locks pipe->inode, then tries to lock inode, but that is + already held by task A + - task A is interrupted, it tries to lock pipe->inode, but fails, as + it is already held by task B + - ABBA deadlock + +Fix this by explicitly ordering locks: the outer lock must be on +target inode and the inner lock (which is later unlocked and relocked) +must be on pipe->inode. This is OK, pipe inodes and target inodes +form two nonoverlapping sets, generic_file_splice_write() and friends +are not called with a target which is a pipe. + +Signed-off-by: Miklos Szeredi +Acked-by: Mark Fasheh +Acked-by: Jens Axboe +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + fs/ocfs2/file.c | 8 ++++++-- + fs/splice.c | 25 ++++++++++++++++++++----- + 2 files changed, 26 insertions(+), 7 deletions(-) + +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -1943,7 +1943,7 @@ static ssize_t ocfs2_file_splice_write(s + out->f_path.dentry->d_name.len, + out->f_path.dentry->d_name.name); + +- inode_double_lock(inode, pipe->inode); ++ mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); + + ret = ocfs2_rw_lock(inode, 1); + if (ret < 0) { +@@ -1958,12 +1958,16 @@ static ssize_t ocfs2_file_splice_write(s + goto out_unlock; + } + ++ if (pipe->inode) ++ mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); + ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags); ++ if (pipe->inode) ++ mutex_unlock(&pipe->inode->i_mutex); + + out_unlock: + ocfs2_rw_unlock(inode, 1); + out: +- inode_double_unlock(inode, pipe->inode); ++ mutex_unlock(&inode->i_mutex); + + mlog_exit(ret); + return ret; +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -735,10 +735,19 @@ ssize_t splice_from_pipe(struct pipe_ino + * ->write_end. Most of the time, these expect i_mutex to + * be held. Since this may result in an ABBA deadlock with + * pipe->inode, we have to order lock acquiry here. ++ * ++ * Outer lock must be inode->i_mutex, as pipe_wait() will ++ * release and reacquire pipe->inode->i_mutex, AND inode must ++ * never be a pipe. + */ +- inode_double_lock(inode, pipe->inode); ++ WARN_ON(S_ISFIFO(inode->i_mode)); ++ mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); ++ if (pipe->inode) ++ mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); + ret = __splice_from_pipe(pipe, &sd, actor); +- inode_double_unlock(inode, pipe->inode); ++ if (pipe->inode) ++ mutex_unlock(&pipe->inode->i_mutex); ++ mutex_unlock(&inode->i_mutex); + + return ret; + } +@@ -829,11 +838,17 @@ generic_file_splice_write(struct pipe_in + }; + ssize_t ret; + +- inode_double_lock(inode, pipe->inode); ++ WARN_ON(S_ISFIFO(inode->i_mode)); ++ mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); + ret = file_remove_suid(out); +- if (likely(!ret)) ++ if (likely(!ret)) { ++ if (pipe->inode) ++ mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); + ret = __splice_from_pipe(pipe, &sd, pipe_to_file); +- inode_double_unlock(inode, pipe->inode); ++ if (pipe->inode) ++ mutex_unlock(&pipe->inode->i_mutex); ++ } ++ mutex_unlock(&inode->i_mutex); + if (ret > 0) { + unsigned long nr_pages; + diff --git a/queue-2.6.28/0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch b/queue-2.6.28/0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch new file mode 100644 index 00000000000..8734fc7f6d7 --- /dev/null +++ b/queue-2.6.28/0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch @@ -0,0 +1,28 @@ +From 37a8bca218bf6c4cad295b7d250c3590f57e3cf6 Mon Sep 17 00:00:00 2001 +From: Akinobu Mita +Date: Tue, 7 Apr 2009 16:25:04 +0000 +Subject: ALSA: hda - add missing comma in ad1884_slave_vols + +From: Akinobu Mita + +upstream commit: bca68467b59a24396554d8dd5979ee363c174854 + +Signed-off-by: Akinobu Mita +Signed-off-by: Takashi Iwai +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/hda/patch_analog.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_analog.c ++++ b/sound/pci/hda/patch_analog.c +@@ -3233,7 +3233,7 @@ static const char *ad1884_slave_vols[] = + "Mic Playback Volume", + "CD Playback Volume", + "Internal Mic Playback Volume", +- "Docking Mic Playback Volume" ++ "Docking Mic Playback Volume", + "Beep Playback Volume", + "IEC958 Playback Volume", + NULL diff --git a/queue-2.6.28/0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch b/queue-2.6.28/0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch new file mode 100644 index 00000000000..7c2c2749c14 --- /dev/null +++ b/queue-2.6.28/0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch @@ -0,0 +1,47 @@ +From 10b9c3cd8848919561d16570759c0146988cb8d5 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Thu, 5 Mar 2009 14:45:55 -0600 +Subject: SCSI: libiscsi: fix iscsi pool error path + +From: Jean Delvare + +upstream commit: f474a37bc48667595b5653a983b635c95ed82a3b + +Memory freeing in iscsi_pool_free() looks wrong to me. Either q->pool +can be NULL and this should be tested before dereferencing it, or it +can't be NULL and it shouldn't be tested at all. As far as I can see, +the only case where q->pool is NULL is on early error in +iscsi_pool_init(). One possible way to fix the bug is thus to not +call iscsi_pool_free() in this case (nothing needs to be freed anyway) +and then we can get rid of the q->pool check. + +Signed-off-by: Jean Delvare +Signed-off-by: Mike Christie +Signed-off-by: James Bottomley +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/libiscsi.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -1862,7 +1862,7 @@ iscsi_pool_init(struct iscsi_pool *q, in + num_arrays++; + q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL); + if (q->pool == NULL) +- goto enomem; ++ return -ENOMEM; + + q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), + GFP_KERNEL, NULL); +@@ -1897,8 +1897,7 @@ void iscsi_pool_free(struct iscsi_pool * + + for (i = 0; i < q->max; i++) + kfree(q->pool[i]); +- if (q->pool) +- kfree(q->pool); ++ kfree(q->pool); + kfree(q->queue); + } + EXPORT_SYMBOL_GPL(iscsi_pool_free); diff --git a/queue-2.6.28/0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch b/queue-2.6.28/0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch new file mode 100644 index 00000000000..0751ec7087f --- /dev/null +++ b/queue-2.6.28/0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch @@ -0,0 +1,50 @@ +From b76d2b612cd5c0c6fb82340f9ec241ca75b942f9 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 1 Apr 2009 13:11:29 -0500 +Subject: SCSI: libiscsi: fix iscsi pool error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +From: Jean Delvare + +upstream commit: fd6e1c14b73dbab89cb76af895d5612e4a8b5522 + +Le lundi 30 mars 2009, Chris Wright a écrit : +> q->queue could be ERR_PTR(-ENOMEM) which will break unwinding +> on error. Make iscsi_pool_free more defensive. +> + +Making the freeing of q->queue dependent on q->pool being set looks +really weird (although it is correct at the moment. But this seems +to be fixable in a much simpler way. + +With the benefit that only the error case is slowed down. In both +cases we have a problem if q->queue contains an error value but it's +not -ENOMEM. Apparently this can't happen today, but it doesn't feel +right to assume this will always be true. Maybe it's the right time +to fix this as well. + +Signed-off-by: Mike Christie +Signed-off-by: James Bottomley +[chrisw: this is a fixlet to f474a37b, also in -stable] +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/libiscsi.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -1866,8 +1866,10 @@ iscsi_pool_init(struct iscsi_pool *q, in + + q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), + GFP_KERNEL, NULL); +- if (q->queue == ERR_PTR(-ENOMEM)) ++ if (IS_ERR(q->queue)) { ++ q->queue = NULL; + goto enomem; ++ } + + for (i = 0; i < max; i++) { + q->pool[i] = kzalloc(item_size, GFP_KERNEL); diff --git a/queue-2.6.28/0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch b/queue-2.6.28/0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch new file mode 100644 index 00000000000..6b84e9f6928 --- /dev/null +++ b/queue-2.6.28/0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch @@ -0,0 +1,163 @@ +From 39cd13c96cfc4d9d5992e93625fe6d6cb4fe3991 Mon Sep 17 00:00:00 2001 +From: Hidetoshi Seto +Date: Thu, 9 Apr 2009 18:20:12 +0000 +Subject: posixtimers, sched: Fix posix clock monotonicity + +From: Hidetoshi Seto + +upstream commit: c5f8d99585d7b5b7e857fabf8aefd0174903a98c + +Impact: Regression fix (against clock_gettime() backwarding bug) + +This patch re-introduces a couple of functions, task_sched_runtime +and thread_group_sched_runtime, which was once removed at the +time of 2.6.28-rc1. + +These functions protect the sampling of thread/process clock with +rq lock. This rq lock is required not to update rq->clock during +the sampling. + +i.e. + The clock_gettime() may return + ((accounted runtime before update) + (delta after update)) + that is less than what it should be. + +v2 -> v3: + - Rename static helper function __task_delta_exec() + to do_task_delta_exec() since -tip tree already has + a __task_delta_exec() of different version. + +v1 -> v2: + - Revises comments of function and patch description. + - Add note about accuracy of thread group's runtime. + +Signed-off-by: Hidetoshi Seto +Acked-by: Peter Zijlstra +LKML-Reference: <49D1CC93.4080401@jp.fujitsu.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + kernel/posix-cpu-timers.c | 7 ++-- + kernel/sched.c | 65 ++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 61 insertions(+), 11 deletions(-) + +--- a/kernel/posix-cpu-timers.c ++++ b/kernel/posix-cpu-timers.c +@@ -294,7 +294,7 @@ static int cpu_clock_sample(const clocki + cpu->cpu = virt_ticks(p); + break; + case CPUCLOCK_SCHED: +- cpu->sched = p->se.sum_exec_runtime + task_delta_exec(p); ++ cpu->sched = task_sched_runtime(p); + break; + } + return 0; +@@ -310,18 +310,19 @@ static int cpu_clock_sample_group(const + { + struct task_cputime cputime; + +- thread_group_cputime(p, &cputime); + switch (CPUCLOCK_WHICH(which_clock)) { + default: + return -EINVAL; + case CPUCLOCK_PROF: ++ thread_group_cputime(p, &cputime); + cpu->cpu = cputime_add(cputime.utime, cputime.stime); + break; + case CPUCLOCK_VIRT: ++ thread_group_cputime(p, &cputime); + cpu->cpu = cputime.utime; + break; + case CPUCLOCK_SCHED: +- cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p); ++ cpu->sched = thread_group_sched_runtime(p); + break; + } + return 0; +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -4064,9 +4064,25 @@ DEFINE_PER_CPU(struct kernel_stat, kstat + EXPORT_PER_CPU_SYMBOL(kstat); + + /* +- * Return any ns on the sched_clock that have not yet been banked in ++ * Return any ns on the sched_clock that have not yet been accounted in + * @p in case that task is currently running. ++ * ++ * Called with task_rq_lock() held on @rq. + */ ++static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq) ++{ ++ u64 ns = 0; ++ ++ if (task_current(rq, p)) { ++ update_rq_clock(rq); ++ ns = rq->clock - p->se.exec_start; ++ if ((s64)ns < 0) ++ ns = 0; ++ } ++ ++ return ns; ++} ++ + unsigned long long task_delta_exec(struct task_struct *p) + { + unsigned long flags; +@@ -4074,16 +4090,49 @@ unsigned long long task_delta_exec(struc + u64 ns = 0; + + rq = task_rq_lock(p, &flags); ++ ns = do_task_delta_exec(p, rq); ++ task_rq_unlock(rq, &flags); + +- if (task_current(rq, p)) { +- u64 delta_exec; ++ return ns; ++} + +- update_rq_clock(rq); +- delta_exec = rq->clock - p->se.exec_start; +- if ((s64)delta_exec > 0) +- ns = delta_exec; +- } ++/* ++ * Return accounted runtime for the task. ++ * In case the task is currently running, return the runtime plus current's ++ * pending runtime that have not been accounted yet. ++ */ ++unsigned long long task_sched_runtime(struct task_struct *p) ++{ ++ unsigned long flags; ++ struct rq *rq; ++ u64 ns = 0; ++ ++ rq = task_rq_lock(p, &flags); ++ ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq); ++ task_rq_unlock(rq, &flags); ++ ++ return ns; ++} + ++/* ++ * Return sum_exec_runtime for the thread group. ++ * In case the task is currently running, return the sum plus current's ++ * pending runtime that have not been accounted yet. ++ * ++ * Note that the thread group might have other running tasks as well, ++ * so the return value not includes other pending runtime that other ++ * running tasks might have. ++ */ ++unsigned long long thread_group_sched_runtime(struct task_struct *p) ++{ ++ struct task_cputime totals; ++ unsigned long flags; ++ struct rq *rq; ++ u64 ns; ++ ++ rq = task_rq_lock(p, &flags); ++ thread_group_cputime(p, &totals); ++ ns = totals.sum_exec_runtime + do_task_delta_exec(p, rq); + task_rq_unlock(rq, &flags); + + return ns; diff --git a/queue-2.6.28/0060-sched-do-not-count-frozen-tasks-toward-load.patch b/queue-2.6.28/0060-sched-do-not-count-frozen-tasks-toward-load.patch new file mode 100644 index 00000000000..bdd47351a60 --- /dev/null +++ b/queue-2.6.28/0060-sched-do-not-count-frozen-tasks-toward-load.patch @@ -0,0 +1,52 @@ +From 3f22ebd2f4d191631a7b867addc8bd99e948873f Mon Sep 17 00:00:00 2001 +From: Nathan Lynch +Date: Thu, 9 Apr 2009 18:20:02 +0000 +Subject: sched: do not count frozen tasks toward load + +From: Nathan Lynch + +upstream commit: e3c8ca8336707062f3f7cb1cd7e6b3c753baccdd + +Freezing tasks via the cgroup freezer causes the load average to climb +because the freezer's current implementation puts frozen tasks in +uninterruptible sleep (D state). + +Some applications which perform job-scheduling functions consult the +load average when making decisions. If a cgroup is frozen, the load +average does not provide a useful measure of the system's utilization +to such applications. This is especially inconvenient if the job +scheduler employs the cgroup freezer as a mechanism for preempting low +priority jobs. Contrast this with using SIGSTOP for the same purpose: +the stopped tasks do not count toward system load. + +Change task_contributes_to_load() to return false if the task is +frozen. This results in /proc/loadavg behavior that better meets +users' expectations. + +Signed-off-by: Nathan Lynch +Acked-by: Andrew Morton +Acked-by: Nigel Cunningham +Tested-by: Nigel Cunningham +Cc: containers@lists.linux-foundation.org +Cc: linux-pm@lists.linux-foundation.org +Cc: Matt Helsley +LKML-Reference: <20090408194512.47a99b95@manatee.lan> +Signed-off-by: Ingo Molnar +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/sched.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -201,7 +201,8 @@ extern unsigned long long time_sync_thre + #define task_is_stopped_or_traced(task) \ + ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0) + #define task_contributes_to_load(task) \ +- ((task->state & TASK_UNINTERRUPTIBLE) != 0) ++ ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \ ++ (task->flags & PF_FROZEN) == 0) + + #define __set_task_state(tsk, state_value) \ + do { (tsk)->state = (state_value); } while (0) diff --git a/queue-2.6.28/0063-add-some-long-missing-capabilities-to-fs_mask.patch b/queue-2.6.28/0063-add-some-long-missing-capabilities-to-fs_mask.patch new file mode 100644 index 00000000000..e2c968bac29 --- /dev/null +++ b/queue-2.6.28/0063-add-some-long-missing-capabilities-to-fs_mask.patch @@ -0,0 +1,80 @@ +From d11a29e323dfd141183cdc918e31acdff02ef450 Mon Sep 17 00:00:00 2001 +From: Serge E. Hallyn +Date: Mon, 13 Apr 2009 17:25:03 +0000 +Subject: add some long-missing capabilities to fs_mask + +From: Serge E. Hallyn + +upstream commit: 0ad30b8fd5fe798aae80df6344b415d8309342cc + +When POSIX capabilities were introduced during the 2.1 Linux +cycle, the fs mask, which represents the capabilities which having +fsuid==0 is supposed to grant, did not include CAP_MKNOD and +CAP_LINUX_IMMUTABLE. However, before capabilities the privilege +to call these did in fact depend upon fsuid==0. + +This patch introduces those capabilities into the fsmask, +restoring the old behavior. + +See the thread starting at http://lkml.org/lkml/2009/3/11/157 for +reference. + +Note that if this fix is deemed valid, then earlier kernel versions (2.4 +and 2.2) ought to be fixed too. + +Changelog: + [Mar 23] Actually delete old CAP_FS_SET definition... + [Mar 20] Updated against J. Bruce Fields's patch + +Reported-by: Igor Zhbanov +Signed-off-by: Serge E. Hallyn +Cc: stable@kernel.org +Cc: J. Bruce Fields +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/capability.h | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +--- a/include/linux/capability.h ++++ b/include/linux/capability.h +@@ -366,7 +366,21 @@ typedef struct kernel_cap_struct { + #define CAP_FOR_EACH_U32(__capi) \ + for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi) + ++/* ++ * CAP_FS_MASK and CAP_NFSD_MASKS: ++ * ++ * The fs mask is all the privileges that fsuid==0 historically meant. ++ * At one time in the past, that included CAP_MKNOD and CAP_LINUX_IMMUTABLE. ++ * ++ * It has never meant setting security.* and trusted.* xattrs. ++ * ++ * We could also define fsmask as follows: ++ * 1. CAP_FS_MASK is the privilege to bypass all fs-related DAC permissions ++ * 2. The security.* and trusted.* xattrs are fs-related MAC permissions ++ */ ++ + # define CAP_FS_MASK_B0 (CAP_TO_MASK(CAP_CHOWN) \ ++ | CAP_TO_MASK(CAP_MKNOD) \ + | CAP_TO_MASK(CAP_DAC_OVERRIDE) \ + | CAP_TO_MASK(CAP_DAC_READ_SEARCH) \ + | CAP_TO_MASK(CAP_FOWNER) \ +@@ -381,11 +395,12 @@ typedef struct kernel_cap_struct { + # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) + # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) + # define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) +-# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } }) ++# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ ++ | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ ++ CAP_FS_MASK_B1 } }) + # define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ +- | CAP_TO_MASK(CAP_SYS_RESOURCE) \ +- | CAP_TO_MASK(CAP_MKNOD), \ +- CAP_FS_MASK_B1 } }) ++ | CAP_TO_MASK(CAP_SYS_RESOURCE), \ ++ CAP_FS_MASK_B1 } }) + + #endif /* _KERNEL_CAPABILITY_U32S != 2 */ + diff --git a/queue-2.6.28/0064-spi-spi_write_then_read-bugfixes.patch b/queue-2.6.28/0064-spi-spi_write_then_read-bugfixes.patch new file mode 100644 index 00000000000..3a5fa0a0401 --- /dev/null +++ b/queue-2.6.28/0064-spi-spi_write_then_read-bugfixes.patch @@ -0,0 +1,81 @@ +From 68890fb0bae12f076377dd6a9371be0289b98b7b Mon Sep 17 00:00:00 2001 +From: David Brownell +Date: Mon, 13 Apr 2009 22:35:03 +0000 +Subject: spi: spi_write_then_read() bugfixes + +From: David Brownell + +upstream commit: bdff549ebeff92b1a6952e5501caf16a6f8898c8 + +The "simplify spi_write_then_read()" patch included two regressions from +the 2.6.27 behaviors: + + - The data it wrote out during the (full duplex) read side + of the transfer was not zeroed. + + - It fails completely on half duplex hardware, such as + Microwire and most "3-wire" SPI variants. + +So, revert that patch. A revised version should be submitted at some +point, which can get the speedup on standard hardware (full duplex) +without breaking on less-capable half-duplex stuff. + +Signed-off-by: David Brownell +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -660,7 +660,7 @@ int spi_write_then_read(struct spi_devic + + int status; + struct spi_message message; +- struct spi_transfer x; ++ struct spi_transfer x[2]; + u8 *local_buf; + + /* Use preallocated DMA-safe buffer. We can't avoid copying here, +@@ -671,9 +671,15 @@ int spi_write_then_read(struct spi_devic + return -EINVAL; + + spi_message_init(&message); +- memset(&x, 0, sizeof x); +- x.len = n_tx + n_rx; +- spi_message_add_tail(&x, &message); ++ memset(x, 0, sizeof x); ++ if (n_tx) { ++ x[0].len = n_tx; ++ spi_message_add_tail(&x[0], &message); ++ } ++ if (n_rx) { ++ x[1].len = n_rx; ++ spi_message_add_tail(&x[1], &message); ++ } + + /* ... unless someone else is using the pre-allocated buffer */ + if (!mutex_trylock(&lock)) { +@@ -684,15 +690,15 @@ int spi_write_then_read(struct spi_devic + local_buf = buf; + + memcpy(local_buf, txbuf, n_tx); +- x.tx_buf = local_buf; +- x.rx_buf = local_buf; ++ x[0].tx_buf = local_buf; ++ x[1].rx_buf = local_buf + n_tx; + + /* do the i/o */ + status = spi_sync(spi, &message); + if (status == 0) +- memcpy(rxbuf, x.rx_buf + n_tx, n_rx); ++ memcpy(rxbuf, x[1].rx_buf, n_rx); + +- if (x.tx_buf == buf) ++ if (x[0].tx_buf == buf) + mutex_unlock(&lock); + else + kfree(local_buf); diff --git a/queue-2.6.28/0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch b/queue-2.6.28/0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch new file mode 100644 index 00000000000..acfe0ae3077 --- /dev/null +++ b/queue-2.6.28/0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch @@ -0,0 +1,62 @@ +From 6c6737beae9981a707c1a4e1e9f1baf7cc47ce5f Mon Sep 17 00:00:00 2001 +From: Paul Mackerras +Date: Wed, 15 Apr 2009 17:25:05 +0000 +Subject: powerpc: Fix data-corrupting bug in __futex_atomic_op + +From: Paul Mackerras + +upstream commit: 306a82881b14d950d59e0b59a55093a07d82aa9a + +Richard Henderson pointed out that the powerpc __futex_atomic_op has a +bug: it will write the wrong value if the stwcx. fails and it has to +retry the lwarx/stwcx. loop, since 'oparg' will have been overwritten +by the result from the first time around the loop. This happens +because it uses the same register for 'oparg' (an input) as it uses +for the result. + +This fixes it by using separate registers for 'oparg' and 'ret'. + +Cc: stable@kernel.org +Signed-off-by: Paul Mackerras +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/include/asm/futex.h | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/include/asm/futex.h ++++ b/arch/powerpc/include/asm/futex.h +@@ -27,7 +27,7 @@ + PPC_LONG "1b,4b,2b,4b\n" \ + ".previous" \ + : "=&r" (oldval), "=&r" (ret) \ +- : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \ ++ : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \ + : "cr0", "memory") + + static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) +@@ -47,19 +47,19 @@ static inline int futex_atomic_op_inuser + + switch (op) { + case FUTEX_OP_SET: +- __futex_atomic_op("", ret, oldval, uaddr, oparg); ++ __futex_atomic_op("mr %1,%4\n", ret, oldval, uaddr, oparg); + break; + case FUTEX_OP_ADD: +- __futex_atomic_op("add %1,%0,%1\n", ret, oldval, uaddr, oparg); ++ __futex_atomic_op("add %1,%0,%4\n", ret, oldval, uaddr, oparg); + break; + case FUTEX_OP_OR: +- __futex_atomic_op("or %1,%0,%1\n", ret, oldval, uaddr, oparg); ++ __futex_atomic_op("or %1,%0,%4\n", ret, oldval, uaddr, oparg); + break; + case FUTEX_OP_ANDN: +- __futex_atomic_op("andc %1,%0,%1\n", ret, oldval, uaddr, oparg); ++ __futex_atomic_op("andc %1,%0,%4\n", ret, oldval, uaddr, oparg); + break; + case FUTEX_OP_XOR: +- __futex_atomic_op("xor %1,%0,%1\n", ret, oldval, uaddr, oparg); ++ __futex_atomic_op("xor %1,%0,%4\n", ret, oldval, uaddr, oparg); + break; + default: + ret = -ENOSYS; diff --git a/queue-2.6.28/0069-hpt366-fix-HPT370-DMA-timeouts.patch b/queue-2.6.28/0069-hpt366-fix-HPT370-DMA-timeouts.patch new file mode 100644 index 00000000000..26b5c74d1b0 --- /dev/null +++ b/queue-2.6.28/0069-hpt366-fix-HPT370-DMA-timeouts.patch @@ -0,0 +1,46 @@ +From 2a3403fd95cbf6f548198be0fd37a056d12a56fe Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Sat, 18 Apr 2009 17:42:19 +0200 +Subject: hpt366: fix HPT370 DMA timeouts + +From: Sergei Shtylyov + +upstream commit: c018f1ee5cf81e58b93d9e93a2ee39cad13dc1ac + +The big driver change in 2.4.19-rc1 introduced a regression for many HPT370[A] +chips -- DMA stopped to work completely, only causing endless timeouts... + +The culprit has been identified (at last!): it turned to be the code resetting +the DMA state machine before each transfer. Stop doing it now as this counter- +measure has clearly caused more harm than good. + +This should fix the kernel.org bug #7703. + +Signed-off-by: Sergei Shtylyov +Signed-off-by: Bartlomiej Zolnierkiewicz +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ide/hpt366.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/ide/hpt366.c ++++ b/drivers/ide/hpt366.c +@@ -114,6 +114,8 @@ + * the register setting lists into the table indexed by the clock selected + * - set the correct hwif->ultra_mask for each individual chip + * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards ++ * - stop resetting HPT370's state machine before each DMA transfer as that has ++ * caused more harm than good + * Sergei Shtylyov, or + */ + +@@ -133,7 +135,7 @@ + #define DRV_NAME "hpt366" + + /* various tuning parameters */ +-#define HPT_RESET_STATE_ENGINE ++#undef HPT_RESET_STATE_ENGINE + #undef HPT_DELAY_INTERRUPT + #define HPT_SERIALIZE_IO 0 + diff --git a/queue-2.6.28/0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch b/queue-2.6.28/0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch new file mode 100644 index 00000000000..072d6503381 --- /dev/null +++ b/queue-2.6.28/0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch @@ -0,0 +1,73 @@ +From d683876908060916ada0091d1db3b09afccb1517 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Tue, 14 Apr 2009 18:39:14 +0400 +Subject: pata_hpt37x: fix HPT370 DMA timeouts + +From: Sergei Shtylyov + +upstream commit: 265b7215aed36941620b65ecfff516200fb190c1 + +The libata driver has copied the code from the IDE driver which caused a post +2.4.18 regression on many HPT370[A] chips -- DMA stopped to work completely, +only causing timeouts. Now remove hpt370_bmdma_start() for good... + +Signed-off-by: Sergei Shtylyov +Signed-off-by: Jeff Garzik +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/pata_hpt37x.c | 22 ++-------------------- + 1 file changed, 2 insertions(+), 20 deletions(-) + +--- a/drivers/ata/pata_hpt37x.c ++++ b/drivers/ata/pata_hpt37x.c +@@ -8,7 +8,7 @@ + * Copyright (C) 1999-2003 Andre Hedrick + * Portions Copyright (C) 2001 Sun Microsystems, Inc. + * Portions Copyright (C) 2003 Red Hat Inc +- * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. ++ * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. + * + * TODO + * Look into engine reset on timeout errors. Should not be required. +@@ -24,7 +24,7 @@ + #include + + #define DRV_NAME "pata_hpt37x" +-#define DRV_VERSION "0.6.11" ++#define DRV_VERSION "0.6.12" + + struct hpt_clock { + u8 xfer_speed; +@@ -445,23 +445,6 @@ static void hpt370_set_dmamode(struct at + } + + /** +- * hpt370_bmdma_start - DMA engine begin +- * @qc: ATA command +- * +- * The 370 and 370A want us to reset the DMA engine each time we +- * use it. The 372 and later are fine. +- */ +- +-static void hpt370_bmdma_start(struct ata_queued_cmd *qc) +-{ +- struct ata_port *ap = qc->ap; +- struct pci_dev *pdev = to_pci_dev(ap->host->dev); +- pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); +- udelay(10); +- ata_bmdma_start(qc); +-} +- +-/** + * hpt370_bmdma_end - DMA engine stop + * @qc: ATA command + * +@@ -598,7 +581,6 @@ static struct scsi_host_template hpt37x_ + static struct ata_port_operations hpt370_port_ops = { + .inherits = &ata_bmdma_port_ops, + +- .bmdma_start = hpt370_bmdma_start, + .bmdma_stop = hpt370_bmdma_stop, + + .mode_filter = hpt370_filter, diff --git a/queue-2.6.28/0071-mm-pass-correct-mm-when-growing-stack.patch b/queue-2.6.28/0071-mm-pass-correct-mm-when-growing-stack.patch new file mode 100644 index 00000000000..b6de878ae88 --- /dev/null +++ b/queue-2.6.28/0071-mm-pass-correct-mm-when-growing-stack.patch @@ -0,0 +1,39 @@ +From 14be1689c96842bd93cbcda4cb0bd4c5cc15a5a0 Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Thu, 16 Apr 2009 21:45:05 +0000 +Subject: mm: pass correct mm when growing stack + +From: Hugh Dickins + +upstream commit: 05fa199d45c54a9bda7aa3ae6537253d6f097aa9 + +Tetsuo Handa reports seeing the WARN_ON(current->mm == NULL) in +security_vm_enough_memory(), when do_execve() is touching the +target mm's stack, to set up its args and environment. + +Yes, a UMH_NO_WAIT or UMH_WAIT_PROC call_usermodehelper() spawns +an mm-less kernel thread to do the exec. And in any case, that +vm_enough_memory check when growing stack ought to be done on the +target mm, not on the execer's mm (though apart from the warning, +it only makes a slight tweak to OVERCOMMIT_NEVER behaviour). + +Reported-by: Tetsuo Handa +Signed-off-by: Hugh Dickins +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + mm/mmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1580,7 +1580,7 @@ static int acct_stack_growth(struct vm_a + * Overcommit.. This must be the final test, as it will + * update security statistics. + */ +- if (security_vm_enough_memory(grow)) ++ if (security_vm_enough_memory_mm(mm, grow)) + return -ENOMEM; + + /* Ok, everything looks good - let it rip */ diff --git a/queue-2.6.28/0072-SCSI-sg-fix-races-during-device-removal.patch b/queue-2.6.28/0072-SCSI-sg-fix-races-during-device-removal.patch new file mode 100644 index 00000000000..cfc21704fa7 --- /dev/null +++ b/queue-2.6.28/0072-SCSI-sg-fix-races-during-device-removal.patch @@ -0,0 +1,741 @@ +From b21c6d2897cd455fa396f4041a0c8165784e949f Mon Sep 17 00:00:00 2001 +From: Tony Battersby +Date: Wed, 21 Jan 2009 14:45:50 -0500 +Subject: SCSI: sg: fix races during device removal + +From: Tony Battersby + +upstream commit: c6517b7942fad663cc1cf3235cbe4207cf769332 + +sg has the following problems related to device removal: + +* opening a sg fd races with removing a device +* closing a sg fd races with removing a device +* /proc/scsi/sg/* access races with removing a device +* command completion races with removing a device +* command completion races with closing a sg fd +* can rmmod sg with active commands + +These problems can cause kernel oopses, memory-use-after-free, or +double-free errors. This patch fixes these problems by using krefs +to manage the lifetime of sg_device and sg_fd. + +Each command submitted to the midlevel holds a reference to sg_fd +until the completion callback. This ensures that sg_fd doesn't go +away if the fd is closed with commands still outstanding. + +sg_fd gets the reference of sg_device (with scsi_device) and also +makes sure that the sg module doesn't go away. + +/proc/scsi/sg/* functions don't play nicely with krefs because they +give information about sg_fds which have been closed but not yet +freed due to still having outstanding commands and sg_devices which +have been removed but not yet freed due to still being referenced +by one or more sg_fds. To deal with this safely without removing +functionality, /proc functions now access sg_device and sg_fd while +holding a lock instead of using kref_get()/kref_put(). + +Signed-off-by: Tony Battersby +Acked-by: Douglas Gilbert +Signed-off-by: James Bottomley +[chrisw: big for -stable, helps fix real bug, and made it through rc2 upstream] +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sg.c | 418 +++++++++++++++++++++++++----------------------------- + 1 file changed, 201 insertions(+), 217 deletions(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -101,6 +101,7 @@ static int scatter_elem_sz_prev = SG_SCA + #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1) + + static int sg_add(struct device *, struct class_interface *); ++static void sg_device_destroy(struct kref *kref); + static void sg_remove(struct device *, struct class_interface *); + + static DEFINE_IDR(sg_index_idr); +@@ -158,6 +159,8 @@ typedef struct sg_fd { /* holds the sta + char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */ + char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */ + char mmap_called; /* 0 -> mmap() never called on this fd */ ++ struct kref f_ref; ++ struct execute_work ew; + } Sg_fd; + + typedef struct sg_device { /* holds the state of each scsi generic device */ +@@ -171,6 +174,7 @@ typedef struct sg_device { /* holds the + char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */ + struct gendisk *disk; + struct cdev * cdev; /* char_dev [sysfs: /sys/cdev/major/sg] */ ++ struct kref d_ref; + } Sg_device; + + static int sg_fasync(int fd, struct file *filp, int mode); +@@ -194,13 +198,14 @@ static void sg_build_reserve(Sg_fd * sfp + static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size); + static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp); + static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev); +-static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp); +-static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp); ++static void sg_remove_sfp(struct kref *); + static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id); + static Sg_request *sg_add_request(Sg_fd * sfp); + static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); + static int sg_res_in_use(Sg_fd * sfp); ++static Sg_device *sg_lookup_dev(int dev); + static Sg_device *sg_get_dev(int dev); ++static void sg_put_dev(Sg_device *sdp); + #ifdef CONFIG_SCSI_PROC_FS + static int sg_last_dev(void); + #endif +@@ -237,22 +242,17 @@ sg_open(struct inode *inode, struct file + nonseekable_open(inode, filp); + SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags)); + sdp = sg_get_dev(dev); +- if ((!sdp) || (!sdp->device)) { +- unlock_kernel(); +- return -ENXIO; +- } +- if (sdp->detached) { +- unlock_kernel(); +- return -ENODEV; ++ if (IS_ERR(sdp)) { ++ retval = PTR_ERR(sdp); ++ sdp = NULL; ++ goto sg_put; + } + + /* This driver's module count bumped by fops_get in */ + /* Prevent the device driver from vanishing while we sleep */ + retval = scsi_device_get(sdp->device); +- if (retval) { +- unlock_kernel(); +- return retval; +- } ++ if (retval) ++ goto sg_put; + + if (!((flags & O_NONBLOCK) || + scsi_block_when_processing_errors(sdp->device))) { +@@ -303,16 +303,20 @@ sg_open(struct inode *inode, struct file + if ((sfp = sg_add_sfp(sdp, dev))) + filp->private_data = sfp; + else { +- if (flags & O_EXCL) ++ if (flags & O_EXCL) { + sdp->exclude = 0; /* undo if error */ ++ wake_up_interruptible(&sdp->o_excl_wait); ++ } + retval = -ENOMEM; + goto error_out; + } +- unlock_kernel(); +- return 0; +- +- error_out: +- scsi_device_put(sdp->device); ++ retval = 0; ++error_out: ++ if (retval) ++ scsi_device_put(sdp->device); ++sg_put: ++ if (sdp) ++ sg_put_dev(sdp); + unlock_kernel(); + return retval; + } +@@ -327,13 +331,13 @@ sg_release(struct inode *inode, struct f + if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) + return -ENXIO; + SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name)); +- if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */ +- if (!sdp->detached) { +- scsi_device_put(sdp->device); +- } +- sdp->exclude = 0; +- wake_up_interruptible(&sdp->o_excl_wait); +- } ++ ++ sfp->closed = 1; ++ ++ sdp->exclude = 0; ++ wake_up_interruptible(&sdp->o_excl_wait); ++ ++ kref_put(&sfp->f_ref, sg_remove_sfp); + return 0; + } + +@@ -755,6 +759,7 @@ sg_common_write(Sg_fd * sfp, Sg_request + hp->duration = jiffies_to_msecs(jiffies); + + srp->rq->timeout = timeout; ++ kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */ + blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk, + srp->rq, 1, sg_rq_end_io); + return 0; +@@ -1247,24 +1252,23 @@ sg_mmap(struct file *filp, struct vm_are + static void sg_rq_end_io(struct request *rq, int uptodate) + { + struct sg_request *srp = rq->end_io_data; +- Sg_device *sdp = NULL; ++ Sg_device *sdp; + Sg_fd *sfp; + unsigned long iflags; + unsigned int ms; + char *sense; +- int result, resid; ++ int result, resid, done = 1; + +- if (NULL == srp) { +- printk(KERN_ERR "sg_cmd_done: NULL request\n"); ++ if (WARN_ON(srp->done != 0)) + return; +- } ++ + sfp = srp->parentfp; +- if (sfp) +- sdp = sfp->parentdp; +- if ((NULL == sdp) || sdp->detached) { +- printk(KERN_INFO "sg_cmd_done: device detached\n"); ++ if (WARN_ON(sfp == NULL)) + return; +- } ++ ++ sdp = sfp->parentdp; ++ if (unlikely(sdp->detached)) ++ printk(KERN_INFO "sg_rq_end_io: device detached\n"); + + sense = rq->sense; + result = rq->errors; +@@ -1303,33 +1307,26 @@ static void sg_rq_end_io(struct request + } + /* Rely on write phase to clean out srp status values, so no "else" */ + +- if (sfp->closed) { /* whoops this fd already released, cleanup */ +- SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, freeing ...\n")); +- sg_finish_rem_req(srp); +- srp = NULL; +- if (NULL == sfp->headrp) { +- SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n")); +- if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ +- scsi_device_put(sdp->device); +- } +- sfp = NULL; +- } +- } else if (srp && srp->orphan) { ++ write_lock_irqsave(&sfp->rq_list_lock, iflags); ++ if (unlikely(srp->orphan)) { + if (sfp->keep_orphan) + srp->sg_io_owned = 0; +- else { +- sg_finish_rem_req(srp); +- srp = NULL; +- } ++ else ++ done = 0; + } +- if (sfp && srp) { +- /* Now wake up any sg_read() that is waiting for this packet. */ +- kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); +- write_lock_irqsave(&sfp->rq_list_lock, iflags); +- srp->done = 1; ++ srp->done = done; ++ write_unlock_irqrestore(&sfp->rq_list_lock, iflags); ++ ++ if (likely(done)) { ++ /* Now wake up any sg_read() that is waiting for this ++ * packet. ++ */ + wake_up_interruptible(&sfp->read_wait); +- write_unlock_irqrestore(&sfp->rq_list_lock, iflags); +- } ++ kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); ++ } else ++ sg_finish_rem_req(srp); /* call with srp->done == 0 */ ++ ++ kref_put(&sfp->f_ref, sg_remove_sfp); + } + + static struct file_operations sg_fops = { +@@ -1364,17 +1361,18 @@ static Sg_device *sg_alloc(struct gendis + printk(KERN_WARNING "kmalloc Sg_device failure\n"); + return ERR_PTR(-ENOMEM); + } +- error = -ENOMEM; ++ + if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) { + printk(KERN_WARNING "idr expansion Sg_device failure\n"); ++ error = -ENOMEM; + goto out; + } + + write_lock_irqsave(&sg_index_lock, iflags); +- error = idr_get_new(&sg_index_idr, sdp, &k); +- write_unlock_irqrestore(&sg_index_lock, iflags); + ++ error = idr_get_new(&sg_index_idr, sdp, &k); + if (error) { ++ write_unlock_irqrestore(&sg_index_lock, iflags); + printk(KERN_WARNING "idr allocation Sg_device failure: %d\n", + error); + goto out; +@@ -1391,6 +1389,9 @@ static Sg_device *sg_alloc(struct gendis + init_waitqueue_head(&sdp->o_excl_wait); + sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments); + sdp->index = k; ++ kref_init(&sdp->d_ref); ++ ++ write_unlock_irqrestore(&sg_index_lock, iflags); + + error = 0; + out: +@@ -1401,6 +1402,8 @@ static Sg_device *sg_alloc(struct gendis + return sdp; + + overflow: ++ idr_remove(&sg_index_idr, k); ++ write_unlock_irqrestore(&sg_index_lock, iflags); + sdev_printk(KERN_WARNING, scsidp, + "Unable to attach sg device type=%d, minor " + "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); +@@ -1488,49 +1491,46 @@ out: + return error; + } + +-static void +-sg_remove(struct device *cl_dev, struct class_interface *cl_intf) ++static void sg_device_destroy(struct kref *kref) ++{ ++ struct sg_device *sdp = container_of(kref, struct sg_device, d_ref); ++ unsigned long flags; ++ ++ /* CAUTION! Note that the device can still be found via idr_find() ++ * even though the refcount is 0. Therefore, do idr_remove() BEFORE ++ * any other cleanup. ++ */ ++ ++ write_lock_irqsave(&sg_index_lock, flags); ++ idr_remove(&sg_index_idr, sdp->index); ++ write_unlock_irqrestore(&sg_index_lock, flags); ++ ++ SCSI_LOG_TIMEOUT(3, ++ printk("sg_device_destroy: %s\n", ++ sdp->disk->disk_name)); ++ ++ put_disk(sdp->disk); ++ kfree(sdp); ++} ++ ++static void sg_remove(struct device *cl_dev, struct class_interface *cl_intf) + { + struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); + Sg_device *sdp = dev_get_drvdata(cl_dev); + unsigned long iflags; + Sg_fd *sfp; +- Sg_fd *tsfp; +- Sg_request *srp; +- Sg_request *tsrp; +- int delay; + +- if (!sdp) ++ if (!sdp || sdp->detached) + return; + +- delay = 0; ++ SCSI_LOG_TIMEOUT(3, printk("sg_remove: %s\n", sdp->disk->disk_name)); ++ ++ /* Need a write lock to set sdp->detached. */ + write_lock_irqsave(&sg_index_lock, iflags); +- if (sdp->headfp) { +- sdp->detached = 1; +- for (sfp = sdp->headfp; sfp; sfp = tsfp) { +- tsfp = sfp->nextfp; +- for (srp = sfp->headrp; srp; srp = tsrp) { +- tsrp = srp->nextrp; +- if (sfp->closed || (0 == sg_srp_done(srp, sfp))) +- sg_finish_rem_req(srp); +- } +- if (sfp->closed) { +- scsi_device_put(sdp->device); +- __sg_remove_sfp(sdp, sfp); +- } else { +- delay = 1; +- wake_up_interruptible(&sfp->read_wait); +- kill_fasync(&sfp->async_qp, SIGPOLL, +- POLL_HUP); +- } +- } +- SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", sdp->index)); +- if (NULL == sdp->headfp) { +- idr_remove(&sg_index_idr, sdp->index); +- } +- } else { /* nothing active, simple case */ +- SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", sdp->index)); +- idr_remove(&sg_index_idr, sdp->index); ++ sdp->detached = 1; ++ for (sfp = sdp->headfp; sfp; sfp = sfp->nextfp) { ++ wake_up_interruptible(&sfp->read_wait); ++ kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP); + } + write_unlock_irqrestore(&sg_index_lock, iflags); + +@@ -1538,13 +1538,8 @@ sg_remove(struct device *cl_dev, struct + device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index)); + cdev_del(sdp->cdev); + sdp->cdev = NULL; +- put_disk(sdp->disk); +- sdp->disk = NULL; +- if (NULL == sdp->headfp) +- kfree(sdp); + +- if (delay) +- msleep(10); /* dirty detach so delay device destruction */ ++ sg_put_dev(sdp); + } + + module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR); +@@ -1939,22 +1934,6 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id) + return resp; + } + +-#ifdef CONFIG_SCSI_PROC_FS +-static Sg_request * +-sg_get_nth_request(Sg_fd * sfp, int nth) +-{ +- Sg_request *resp; +- unsigned long iflags; +- int k; +- +- read_lock_irqsave(&sfp->rq_list_lock, iflags); +- for (k = 0, resp = sfp->headrp; resp && (k < nth); +- ++k, resp = resp->nextrp) ; +- read_unlock_irqrestore(&sfp->rq_list_lock, iflags); +- return resp; +-} +-#endif +- + /* always adds to end of list */ + static Sg_request * + sg_add_request(Sg_fd * sfp) +@@ -2030,22 +2009,6 @@ sg_remove_request(Sg_fd * sfp, Sg_reques + return res; + } + +-#ifdef CONFIG_SCSI_PROC_FS +-static Sg_fd * +-sg_get_nth_sfp(Sg_device * sdp, int nth) +-{ +- Sg_fd *resp; +- unsigned long iflags; +- int k; +- +- read_lock_irqsave(&sg_index_lock, iflags); +- for (k = 0, resp = sdp->headfp; resp && (k < nth); +- ++k, resp = resp->nextfp) ; +- read_unlock_irqrestore(&sg_index_lock, iflags); +- return resp; +-} +-#endif +- + static Sg_fd * + sg_add_sfp(Sg_device * sdp, int dev) + { +@@ -2060,6 +2023,7 @@ sg_add_sfp(Sg_device * sdp, int dev) + init_waitqueue_head(&sfp->read_wait); + rwlock_init(&sfp->rq_list_lock); + ++ kref_init(&sfp->f_ref); + sfp->timeout = SG_DEFAULT_TIMEOUT; + sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER; + sfp->force_packid = SG_DEF_FORCE_PACK_ID; +@@ -2087,15 +2051,54 @@ sg_add_sfp(Sg_device * sdp, int dev) + sg_build_reserve(sfp, bufflen); + SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n", + sfp->reserve.bufflen, sfp->reserve.k_use_sg)); ++ ++ kref_get(&sdp->d_ref); ++ __module_get(THIS_MODULE); + return sfp; + } + +-static void +-__sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) ++static void sg_remove_sfp_usercontext(struct work_struct *work) ++{ ++ struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work); ++ struct sg_device *sdp = sfp->parentdp; ++ ++ /* Cleanup any responses which were never read(). */ ++ while (sfp->headrp) ++ sg_finish_rem_req(sfp->headrp); ++ ++ if (sfp->reserve.bufflen > 0) { ++ SCSI_LOG_TIMEOUT(6, ++ printk("sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", ++ (int) sfp->reserve.bufflen, ++ (int) sfp->reserve.k_use_sg)); ++ sg_remove_scat(&sfp->reserve); ++ } ++ ++ SCSI_LOG_TIMEOUT(6, ++ printk("sg_remove_sfp: %s, sfp=0x%p\n", ++ sdp->disk->disk_name, ++ sfp)); ++ kfree(sfp); ++ ++ scsi_device_put(sdp->device); ++ sg_put_dev(sdp); ++ module_put(THIS_MODULE); ++} ++ ++static void sg_remove_sfp(struct kref *kref) + { ++ struct sg_fd *sfp = container_of(kref, struct sg_fd, f_ref); ++ struct sg_device *sdp = sfp->parentdp; + Sg_fd *fp; + Sg_fd *prev_fp; ++ unsigned long iflags; ++ ++ /* CAUTION! Note that sfp can still be found by walking sdp->headfp ++ * even though the refcount is now 0. Therefore, unlink sfp from ++ * sdp->headfp BEFORE doing any other cleanup. ++ */ + ++ write_lock_irqsave(&sg_index_lock, iflags); + prev_fp = sdp->headfp; + if (sfp == prev_fp) + sdp->headfp = prev_fp->nextfp; +@@ -2108,54 +2111,10 @@ __sg_remove_sfp(Sg_device * sdp, Sg_fd * + prev_fp = fp; + } + } +- if (sfp->reserve.bufflen > 0) { +- SCSI_LOG_TIMEOUT(6, +- printk("__sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", +- (int) sfp->reserve.bufflen, (int) sfp->reserve.k_use_sg)); +- sg_remove_scat(&sfp->reserve); +- } +- sfp->parentdp = NULL; +- SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp: sfp=0x%p\n", sfp)); +- kfree(sfp); +-} +- +-/* Returns 0 in normal case, 1 when detached and sdp object removed */ +-static int +-sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) +-{ +- Sg_request *srp; +- Sg_request *tsrp; +- int dirty = 0; +- int res = 0; +- +- for (srp = sfp->headrp; srp; srp = tsrp) { +- tsrp = srp->nextrp; +- if (sg_srp_done(srp, sfp)) +- sg_finish_rem_req(srp); +- else +- ++dirty; +- } +- if (0 == dirty) { +- unsigned long iflags; ++ write_unlock_irqrestore(&sg_index_lock, iflags); ++ wake_up_interruptible(&sdp->o_excl_wait); + +- write_lock_irqsave(&sg_index_lock, iflags); +- __sg_remove_sfp(sdp, sfp); +- if (sdp->detached && (NULL == sdp->headfp)) { +- idr_remove(&sg_index_idr, sdp->index); +- kfree(sdp); +- res = 1; +- } +- write_unlock_irqrestore(&sg_index_lock, iflags); +- } else { +- /* MOD_INC's to inhibit unloading sg and associated adapter driver */ +- /* only bump the access_count if we actually succeeded in +- * throwing another counter on the host module */ +- scsi_device_get(sdp->device); /* XXX: retval ignored? */ +- sfp->closed = 1; /* flag dirty state on this fd */ +- SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n", +- dirty)); +- } +- return res; ++ execute_in_process_context(sg_remove_sfp_usercontext, &sfp->ew); + } + + static int +@@ -2197,19 +2156,38 @@ sg_last_dev(void) + } + #endif + +-static Sg_device * +-sg_get_dev(int dev) ++/* must be called with sg_index_lock held */ ++static Sg_device *sg_lookup_dev(int dev) + { +- Sg_device *sdp; +- unsigned long iflags; ++ return idr_find(&sg_index_idr, dev); ++} + +- read_lock_irqsave(&sg_index_lock, iflags); +- sdp = idr_find(&sg_index_idr, dev); +- read_unlock_irqrestore(&sg_index_lock, iflags); ++static Sg_device *sg_get_dev(int dev) ++{ ++ struct sg_device *sdp; ++ unsigned long flags; ++ ++ read_lock_irqsave(&sg_index_lock, flags); ++ sdp = sg_lookup_dev(dev); ++ if (!sdp) ++ sdp = ERR_PTR(-ENXIO); ++ else if (sdp->detached) { ++ /* If sdp->detached, then the refcount may already be 0, in ++ * which case it would be a bug to do kref_get(). ++ */ ++ sdp = ERR_PTR(-ENODEV); ++ } else ++ kref_get(&sdp->d_ref); ++ read_unlock_irqrestore(&sg_index_lock, flags); + + return sdp; + } + ++static void sg_put_dev(struct sg_device *sdp) ++{ ++ kref_put(&sdp->d_ref, sg_device_destroy); ++} ++ + #ifdef CONFIG_SCSI_PROC_FS + + static struct proc_dir_entry *sg_proc_sgp = NULL; +@@ -2466,8 +2444,10 @@ static int sg_proc_seq_show_dev(struct s + struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; + Sg_device *sdp; + struct scsi_device *scsidp; ++ unsigned long iflags; + +- sdp = it ? sg_get_dev(it->index) : NULL; ++ read_lock_irqsave(&sg_index_lock, iflags); ++ sdp = it ? sg_lookup_dev(it->index) : NULL; + if (sdp && (scsidp = sdp->device) && (!sdp->detached)) + seq_printf(s, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", + scsidp->host->host_no, scsidp->channel, +@@ -2478,6 +2458,7 @@ static int sg_proc_seq_show_dev(struct s + (int) scsi_device_online(scsidp)); + else + seq_printf(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n"); ++ read_unlock_irqrestore(&sg_index_lock, iflags); + return 0; + } + +@@ -2491,16 +2472,20 @@ static int sg_proc_seq_show_devstrs(stru + struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; + Sg_device *sdp; + struct scsi_device *scsidp; ++ unsigned long iflags; + +- sdp = it ? sg_get_dev(it->index) : NULL; ++ read_lock_irqsave(&sg_index_lock, iflags); ++ sdp = it ? sg_lookup_dev(it->index) : NULL; + if (sdp && (scsidp = sdp->device) && (!sdp->detached)) + seq_printf(s, "%8.8s\t%16.16s\t%4.4s\n", + scsidp->vendor, scsidp->model, scsidp->rev); + else + seq_printf(s, "\n"); ++ read_unlock_irqrestore(&sg_index_lock, iflags); + return 0; + } + ++/* must be called while holding sg_index_lock */ + static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + { + int k, m, new_interface, blen, usg; +@@ -2510,7 +2495,8 @@ static void sg_proc_debug_helper(struct + const char * cp; + unsigned int ms; + +- for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) { ++ for (k = 0, fp = sdp->headfp; fp != NULL; ++k, fp = fp->nextfp) { ++ read_lock(&fp->rq_list_lock); /* irqs already disabled */ + seq_printf(s, " FD(%d): timeout=%dms bufflen=%d " + "(res)sgat=%d low_dma=%d\n", k + 1, + jiffies_to_msecs(fp->timeout), +@@ -2520,7 +2506,9 @@ static void sg_proc_debug_helper(struct + seq_printf(s, " cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n", + (int) fp->cmd_q, (int) fp->force_packid, + (int) fp->keep_orphan, (int) fp->closed); +- for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) { ++ for (m = 0, srp = fp->headrp; ++ srp != NULL; ++ ++m, srp = srp->nextrp) { + hp = &srp->header; + new_interface = (hp->interface_id == '\0') ? 0 : 1; + if (srp->res_used) { +@@ -2557,6 +2545,7 @@ static void sg_proc_debug_helper(struct + } + if (0 == m) + seq_printf(s, " No requests active\n"); ++ read_unlock(&fp->rq_list_lock); + } + } + +@@ -2569,39 +2558,34 @@ static int sg_proc_seq_show_debug(struct + { + struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; + Sg_device *sdp; ++ unsigned long iflags; + + if (it && (0 == it->index)) { + seq_printf(s, "max_active_device=%d(origin 1)\n", + (int)it->max); + seq_printf(s, " def_reserved_size=%d\n", sg_big_buff); + } +- sdp = it ? sg_get_dev(it->index) : NULL; +- if (sdp) { +- struct scsi_device *scsidp = sdp->device; + +- if (NULL == scsidp) { +- seq_printf(s, "device %d detached ??\n", +- (int)it->index); +- return 0; +- } ++ read_lock_irqsave(&sg_index_lock, iflags); ++ sdp = it ? sg_lookup_dev(it->index) : NULL; ++ if (sdp && sdp->headfp) { ++ struct scsi_device *scsidp = sdp->device; + +- if (sg_get_nth_sfp(sdp, 0)) { +- seq_printf(s, " >>> device=%s ", +- sdp->disk->disk_name); +- if (sdp->detached) +- seq_printf(s, "detached pending close "); +- else +- seq_printf +- (s, "scsi%d chan=%d id=%d lun=%d em=%d", +- scsidp->host->host_no, +- scsidp->channel, scsidp->id, +- scsidp->lun, +- scsidp->host->hostt->emulated); +- seq_printf(s, " sg_tablesize=%d excl=%d\n", +- sdp->sg_tablesize, sdp->exclude); +- } ++ seq_printf(s, " >>> device=%s ", sdp->disk->disk_name); ++ if (sdp->detached) ++ seq_printf(s, "detached pending close "); ++ else ++ seq_printf ++ (s, "scsi%d chan=%d id=%d lun=%d em=%d", ++ scsidp->host->host_no, ++ scsidp->channel, scsidp->id, ++ scsidp->lun, ++ scsidp->host->hostt->emulated); ++ seq_printf(s, " sg_tablesize=%d excl=%d\n", ++ sdp->sg_tablesize, sdp->exclude); + sg_proc_debug_helper(s, sdp); + } ++ read_unlock_irqrestore(&sg_index_lock, iflags); + return 0; + } + diff --git a/queue-2.6.28/0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch b/queue-2.6.28/0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch new file mode 100644 index 00000000000..cd9981c11d3 --- /dev/null +++ b/queue-2.6.28/0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch @@ -0,0 +1,126 @@ +From d4845ceede8c4087233198d2847b788a4e6f65b5 Mon Sep 17 00:00:00 2001 +From: Tony Battersby +Date: Tue, 20 Jan 2009 17:00:09 -0500 +Subject: SCSI: sg: fix races with ioctl(SG_IO) + +From: Tony Battersby + +upstream commit: a2dd3b4cea335713b58996bb07b3abcde1175f47 + +sg_io_owned needs to be set before the command is sent to the midlevel; +otherwise, a quickly-completing command may cause a different CPU +to see "srp->done == 1 && !srp->sg_io_owned", which would lead to +incorrect behavior. + +Check srp->done and set srp->orphan while holding rq_list_lock to +prevent races with sg_rq_end_io(). + +There is no need to check sfp->closed from read/write/ioctl/poll/etc. +since the kernel guarantees that this won't happen. + +The usefulness of sg_srp_done() was questionable before; now it is +definitely not needed. + +Signed-off-by: Tony Battersby +Acked-by: Douglas Gilbert +Signed-off-by: James Bottomley +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sg.c | 39 ++++++++++++++------------------------- + 1 file changed, 14 insertions(+), 25 deletions(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -189,7 +189,7 @@ static ssize_t sg_new_read(Sg_fd * sfp, + Sg_request * srp); + static ssize_t sg_new_write(Sg_fd *sfp, struct file *file, + const char __user *buf, size_t count, int blocking, +- int read_only, Sg_request **o_srp); ++ int read_only, int sg_io_owned, Sg_request **o_srp); + static int sg_common_write(Sg_fd * sfp, Sg_request * srp, + unsigned char *cmnd, int timeout, int blocking); + static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer); +@@ -561,7 +561,8 @@ sg_write(struct file *filp, const char _ + return -EFAULT; + blocking = !(filp->f_flags & O_NONBLOCK); + if (old_hdr.reply_len < 0) +- return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL); ++ return sg_new_write(sfp, filp, buf, count, ++ blocking, 0, 0, NULL); + if (count < (SZ_SG_HEADER + 6)) + return -EIO; /* The minimum scsi command length is 6 bytes. */ + +@@ -642,7 +643,7 @@ sg_write(struct file *filp, const char _ + + static ssize_t + sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, +- size_t count, int blocking, int read_only, ++ size_t count, int blocking, int read_only, int sg_io_owned, + Sg_request **o_srp) + { + int k; +@@ -662,6 +663,7 @@ sg_new_write(Sg_fd *sfp, struct file *fi + SCSI_LOG_TIMEOUT(1, printk("sg_new_write: queue full\n")); + return -EDOM; + } ++ srp->sg_io_owned = sg_io_owned; + hp = &srp->header; + if (__copy_from_user(hp, buf, SZ_SG_IO_HDR)) { + sg_remove_request(sfp, srp); +@@ -766,18 +768,6 @@ sg_common_write(Sg_fd * sfp, Sg_request + } + + static int +-sg_srp_done(Sg_request *srp, Sg_fd *sfp) +-{ +- unsigned long iflags; +- int done; +- +- read_lock_irqsave(&sfp->rq_list_lock, iflags); +- done = srp->done; +- read_unlock_irqrestore(&sfp->rq_list_lock, iflags); +- return done; +-} +- +-static int + sg_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd_in, unsigned long arg) + { +@@ -809,27 +799,26 @@ sg_ioctl(struct inode *inode, struct fil + return -EFAULT; + result = + sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, +- blocking, read_only, &srp); ++ blocking, read_only, 1, &srp); + if (result < 0) + return result; +- srp->sg_io_owned = 1; + while (1) { + result = 0; /* following macro to beat race condition */ + __wait_event_interruptible(sfp->read_wait, +- (sdp->detached || sfp->closed || sg_srp_done(srp, sfp)), +- result); ++ (srp->done || sdp->detached), ++ result); + if (sdp->detached) + return -ENODEV; +- if (sfp->closed) +- return 0; /* request packet dropped already */ +- if (0 == result) ++ write_lock_irq(&sfp->rq_list_lock); ++ if (srp->done) { ++ srp->done = 2; ++ write_unlock_irq(&sfp->rq_list_lock); + break; ++ } + srp->orphan = 1; ++ write_unlock_irq(&sfp->rq_list_lock); + return result; /* -ERESTARTSYS because signal hit process */ + } +- write_lock_irqsave(&sfp->rq_list_lock, iflags); +- srp->done = 2; +- write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp); + return (result < 0) ? result : 0; + } diff --git a/queue-2.6.28/0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch b/queue-2.6.28/0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch new file mode 100644 index 00000000000..a8247369a3d --- /dev/null +++ b/queue-2.6.28/0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch @@ -0,0 +1,81 @@ +From 74c646d9ca31798ec2bf862f5b7e1737b543d066 Mon Sep 17 00:00:00 2001 +From: FUJITA Tomonori +Date: Wed, 4 Feb 2009 11:36:27 +0900 +Subject: SCSI: sg: avoid blk_put_request/blk_rq_unmap_user in interrupt + +From: FUJITA Tomonori + +upstream commit: c96952ed7031e7c576ecf90cf95b8ec099d5295a + +This fixes the following oops: + +http://marc.info/?l=linux-kernel&m=123316111415677&w=2 + +You can reproduce this bug by interrupting a program before a sg +response completes. This leads to the special sg state (the orphan +state), then sg calls blk_put_request in interrupt (rq->end_io). + +The above bug report shows the recursive lock problem because sg calls +blk_put_request in interrupt. We could call __blk_put_request here +instead however we also need to handle blk_rq_unmap_user here, which +can't be called in interrupt too. + +In the orphan state, we don't need to care about the data transfer +(the program revoked the command) so adding 'just free the resource' +mode to blk_rq_unmap_user is a possible option. + +I prefer to avoid complicating the blk mapping API when possible. I +change the orphan state to call sg_finish_rem_req via +execute_in_process_context. We hold sg_fd->kref so sg_fd doesn't go +away until keventd_wq finishes our work. copy_from_user/to_user fails +so blk_rq_unmap_user just frees the resource without the data +transfer. + +Signed-off-by: FUJITA Tomonori +Acked-by: Douglas Gilbert +Signed-off-by: James Bottomley +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sg.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -138,6 +138,7 @@ typedef struct sg_request { /* SG_MAX_QU + volatile char done; /* 0->before bh, 1->before read, 2->read */ + struct request *rq; + struct bio *bio; ++ struct execute_work ew; + } Sg_request; + + typedef struct sg_fd { /* holds the state of a file descriptor */ +@@ -1234,6 +1235,15 @@ sg_mmap(struct file *filp, struct vm_are + return 0; + } + ++static void sg_rq_end_io_usercontext(struct work_struct *work) ++{ ++ struct sg_request *srp = container_of(work, struct sg_request, ew.work); ++ struct sg_fd *sfp = srp->parentfp; ++ ++ sg_finish_rem_req(srp); ++ kref_put(&sfp->f_ref, sg_remove_sfp); ++} ++ + /* + * This function is a "bottom half" handler that is called by the mid + * level when a command is completed (or has failed). +@@ -1312,10 +1322,9 @@ static void sg_rq_end_io(struct request + */ + wake_up_interruptible(&sfp->read_wait); + kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); ++ kref_put(&sfp->f_ref, sg_remove_sfp); + } else +- sg_finish_rem_req(srp); /* call with srp->done == 0 */ +- +- kref_put(&sfp->f_ref, sg_remove_sfp); ++ execute_in_process_context(sg_rq_end_io_usercontext, &srp->ew); + } + + static struct file_operations sg_fops = { diff --git a/queue-2.6.28/0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch b/queue-2.6.28/0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch new file mode 100644 index 00000000000..6c569615546 --- /dev/null +++ b/queue-2.6.28/0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch @@ -0,0 +1,48 @@ +From 5c435c37e2652e5d066dc81fcc108a0dffbdb33d Mon Sep 17 00:00:00 2001 +From: Jonathan McDowell +Date: Fri, 17 Apr 2009 21:20:10 +0000 +Subject: usb gadget: fix ethernet link reports to ethtool + +From: Jonathan McDowell + +upstream commit: 237e75bf1e558f7330f8deb167fa3116405bef2c + +The g_ether USB gadget driver currently decides whether or not there's a +link to report back for eth_get_link based on if the USB link speed is +set. The USB gadget speed is however often set even before the device is +enumerated. It seems more sensible to only report a "link" if we're +actually connected to a host that wants to talk to us. The patch below +does this for me - tested with the PXA27x UDC driver. + +Signed-off-by: Jonathan McDowell +Signed-off-by: David Brownell +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Chris Wright +--- + drivers/usb/gadget/u_ether.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/usb/gadget/u_ether.c ++++ b/drivers/usb/gadget/u_ether.c +@@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_d + strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); + } + +-static u32 eth_get_link(struct net_device *net) +-{ +- struct eth_dev *dev = netdev_priv(net); +- return dev->gadget->speed != USB_SPEED_UNKNOWN; +-} +- + /* REVISIT can also support: + * - WOL (by tracking suspends and issuing remote wakeup) + * - msglevel (implies updated messaging) +@@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_devic + + static struct ethtool_ops ops = { + .get_drvinfo = eth_get_drvinfo, +- .get_link = eth_get_link ++ .get_link = ethtool_op_get_link, + }; + + static void defer_kevent(struct eth_dev *dev, int flag) diff --git a/queue-2.6.28/0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch b/queue-2.6.28/0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch new file mode 100644 index 00000000000..f2bcbe96304 --- /dev/null +++ b/queue-2.6.28/0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch @@ -0,0 +1,43 @@ +From 082240d79158decfc9918b96487da38a750b4d1d Mon Sep 17 00:00:00 2001 +From: Peter Korsgaard +Date: Fri, 17 Apr 2009 21:20:07 +0000 +Subject: USB: ftdi_sio: add vendor/project id for JETI specbos 1201 spectrometer + +From: Peter Korsgaard + +upstream commit: ae27d84351f1f3568118318a8c40ff3a154bd629 + +Signed-off-by: Peter Korsgaard +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Chris Wright +--- + drivers/usb/serial/ftdi_sio.c | 1 + + drivers/usb/serial/ftdi_sio.h | 7 +++++++ + 2 files changed, 8 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -665,6 +665,7 @@ static struct usb_device_id id_table_com + { USB_DEVICE(DE_VID, WHT_PID) }, + { USB_DEVICE(ADI_VID, ADI_GNICE_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, ++ { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, + { }, /* Optional parameter entry */ + { } /* Terminating entry */ + }; +--- a/drivers/usb/serial/ftdi_sio.h ++++ b/drivers/usb/serial/ftdi_sio.h +@@ -901,6 +901,13 @@ + #define ADI_GNICE_PID 0xF000 + + /* ++ * JETI SPECTROMETER SPECBOS 1201 ++ * http://www.jeti.com/products/sys/scb/scb1201.php ++ */ ++#define JETI_VID 0x0c6c ++#define JETI_SPC1201_PID 0x04b2 ++ ++/* + * BmRequestType: 1100 0000b + * bRequest: FTDI_E2_READ + * wValue: 0 diff --git a/queue-2.6.28/0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch b/queue-2.6.28/0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch new file mode 100644 index 00000000000..a905a02a612 --- /dev/null +++ b/queue-2.6.28/0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch @@ -0,0 +1,29 @@ +From 4be149f9b684906505d49932fd18e1f17721b30f Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Fri, 17 Apr 2009 21:20:06 +0000 +Subject: USB: fix oops in cdc-wdm in case of malformed descriptors + +From: Oliver Neukum + +upstream commit: e13c594f3a1fc2c78e7a20d1a07974f71e4b448f + +cdc-wdm needs to ignore extremely malformed descriptors. + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Chris Wright +--- + drivers/usb/class/cdc-wdm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -652,7 +652,7 @@ next_desc: + + iface = &intf->altsetting[0]; + ep = &iface->endpoint[0].desc; +- if (!usb_endpoint_is_int_in(ep)) { ++ if (!ep || !usb_endpoint_is_int_in(ep)) { + rv = -EINVAL; + goto err; + } diff --git a/queue-2.6.28/0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch b/queue-2.6.28/0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch new file mode 100644 index 00000000000..903575de040 --- /dev/null +++ b/queue-2.6.28/0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch @@ -0,0 +1,40 @@ +From 35fe207a082d775b0bbaac3f49a9dc2d7c02779c Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 17 Apr 2009 21:20:03 +0000 +Subject: USB: usb-storage: augment unusual_devs entry for Simple Tech/Datafab + +From: Alan Stern + +upstream commit: e4813eec8d47c8299d968bd5349dc881fa481c26 + +This patch (as1227) adds the MAX_SECTORS_64 flag to the unusual_devs +entry for the Simple Tech/Datafab controller. This fixes Bugzilla +#12882. + +Signed-off-by: Alan Stern +Reported-and-tested-by: binbin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Chris Wright +--- + drivers/usb/storage/unusual_devs.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1164,12 +1164,14 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0x + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +-/* Reported by Rauch Wolke */ ++/* Reported by Rauch Wolke ++ * and augmented by binbin (Bugzilla #12882) ++ */ + UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, + "Simple Tech/Datafab", + "CF+SM Reader", + US_SC_DEVICE, US_PR_DEVICE, NULL, +- US_FL_IGNORE_RESIDUE ), ++ US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ), + + /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant + * to the USB storage specification in two ways: diff --git a/queue-2.6.28/0090-Input-gameport-fix-attach-driver-code.patch b/queue-2.6.28/0090-Input-gameport-fix-attach-driver-code.patch new file mode 100644 index 00000000000..78c0735babf --- /dev/null +++ b/queue-2.6.28/0090-Input-gameport-fix-attach-driver-code.patch @@ -0,0 +1,71 @@ +From fb1c95cd6b1b0522bf0f7bedc0e1abc3b05d0607 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 13 Apr 2009 15:27:49 -0700 +Subject: Input: gameport - fix attach driver code + +From: Dmitry Torokhov + +upstream commit: 4ced8e7cb990a2c3bbf0ac7f27b35c890e7ce895 + +The commit 6902c0bead4ce266226fc0c5b3828b850bdc884a that moved +driver registration out of kgameportd thread was incomplete and +did not add the code necessary to actually attach driver to +already registered devices, rectify that. + +Signed-off-by: Dmitry Torokhov +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/gameport/gameport.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/input/gameport/gameport.c ++++ b/drivers/input/gameport/gameport.c +@@ -50,9 +50,8 @@ static LIST_HEAD(gameport_list); + + static struct bus_type gameport_bus; + +-static void gameport_add_driver(struct gameport_driver *drv); + static void gameport_add_port(struct gameport *gameport); +-static void gameport_destroy_port(struct gameport *gameport); ++static void gameport_attach_driver(struct gameport_driver *drv); + static void gameport_reconnect_port(struct gameport *gameport); + static void gameport_disconnect_port(struct gameport *gameport); + +@@ -230,7 +229,6 @@ static void gameport_find_driver(struct + + enum gameport_event_type { + GAMEPORT_REGISTER_PORT, +- GAMEPORT_REGISTER_DRIVER, + GAMEPORT_ATTACH_DRIVER, + }; + +@@ -374,8 +372,8 @@ static void gameport_handle_event(void) + gameport_add_port(event->object); + break; + +- case GAMEPORT_REGISTER_DRIVER: +- gameport_add_driver(event->object); ++ case GAMEPORT_ATTACH_DRIVER: ++ gameport_attach_driver(event->object); + break; + + default: +@@ -707,14 +705,14 @@ static int gameport_driver_remove(struct + return 0; + } + +-static void gameport_add_driver(struct gameport_driver *drv) ++static void gameport_attach_driver(struct gameport_driver *drv) + { + int error; + +- error = driver_register(&drv->driver); ++ error = driver_attach(&drv->driver); + if (error) + printk(KERN_ERR +- "gameport: driver_register() failed for %s, error: %d\n", ++ "gameport: driver_attach() failed for %s, error: %d\n", + drv->driver.name, error); + } + diff --git a/queue-2.6.28/0093-agp-zero-pages-before-sending-to-userspace.patch b/queue-2.6.28/0093-agp-zero-pages-before-sending-to-userspace.patch new file mode 100644 index 00000000000..a9acf13a057 --- /dev/null +++ b/queue-2.6.28/0093-agp-zero-pages-before-sending-to-userspace.patch @@ -0,0 +1,43 @@ +From 0702b646e5bdc16af64ef6f663e5275a02bf40cd Mon Sep 17 00:00:00 2001 +From: Shaohua Li +Date: Mon, 20 Apr 2009 10:08:35 +1000 +Subject: agp: zero pages before sending to userspace + +From: Shaohua Li + +upstream commit: 59de2bebabc5027f93df999d59cc65df591c3e6e + +CVE-2009-1192 + +AGP pages might be mapped into userspace finally, so the pages should be +set to zero before userspace can use it. Otherwise there is potential +information leakage. + +Signed-off-by: Shaohua Li +Signed-off-by: Dave Airlie +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/agp/generic.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/char/agp/generic.c ++++ b/drivers/char/agp/generic.c +@@ -1226,7 +1226,7 @@ int agp_generic_alloc_pages(struct agp_b + int i, ret = -ENOMEM; + + for (i = 0; i < num_pages; i++) { +- page = alloc_page(GFP_KERNEL | GFP_DMA32); ++ page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); + /* agp_free_memory() needs gart address */ + if (page == NULL) + goto out; +@@ -1257,7 +1257,7 @@ void *agp_generic_alloc_page(struct agp_ + { + struct page * page; + +- page = alloc_page(GFP_KERNEL | GFP_DMA32); ++ page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); + if (page == NULL) + return NULL; + diff --git a/queue-2.6.28/0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch b/queue-2.6.28/0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch new file mode 100644 index 00000000000..98e11d2ab8b --- /dev/null +++ b/queue-2.6.28/0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch @@ -0,0 +1,53 @@ +From 5a9b5af39e948919f272867516faa61c093124f6 Mon Sep 17 00:00:00 2001 +From: Akinobu Mita +Date: Tue, 21 Apr 2009 21:20:04 +0000 +Subject: hugetlbfs: return negative error code for bad mount option + +From: Akinobu Mita + +upstream commit: c12ddba09394c60e1120e6997794fa6ed52da884 + +This fixes the following BUG: + + # mount -o size=MM -t hugetlbfs none /huge + hugetlbfs: Bad value 'MM' for mount option 'size=MM' + ------------[ cut here ]------------ + kernel BUG at fs/super.c:996! + +Due to + + BUG_ON(!mnt->mnt_sb); + +in vfs_kern_mount(). + +Also, remove unused #include + +Cc: William Irwin +Signed-off-by: Akinobu Mita +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +Signed-off-by: Greg Kroah-Hartman +--- + fs/hugetlbfs/inode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -26,7 +26,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -838,7 +837,7 @@ hugetlbfs_parse_options(char *options, s + bad_val: + printk(KERN_ERR "hugetlbfs: Bad value '%s' for mount option '%s'\n", + args[0].from, p); +- return 1; ++ return -EINVAL; + } + + static int diff --git a/queue-2.6.28/bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch b/queue-2.6.28/bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch index 46cffa95bc5..8dc00f291af 100644 --- a/queue-2.6.28/bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch +++ b/queue-2.6.28/bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch @@ -3,6 +3,7 @@ From: Tilman Schmidt Date: Wed, 15 Apr 2009 03:25:43 -0700 Subject: bas_gigaset: correctly allocate USB interrupt transfer buffer +From: Tilman Schmidt [ Upstream commit 170ebf85160dd128e1c4206cc197cce7d1424705 ] diff --git a/queue-2.6.28/bonding-fix-updating-of-speed-duplex-changes.patch b/queue-2.6.28/bonding-fix-updating-of-speed-duplex-changes.patch index d538e245dd1..d89f2ea3606 100644 --- a/queue-2.6.28/bonding-fix-updating-of-speed-duplex-changes.patch +++ b/queue-2.6.28/bonding-fix-updating-of-speed-duplex-changes.patch @@ -3,6 +3,7 @@ From: Jay Vosburgh Date: Sat, 4 Apr 2009 17:23:15 -0700 Subject: bonding: Fix updating of speed/duplex changes +From: Jay Vosburgh [ Upstream commit 17d04500e2528217de5fe967599f98ee84348a9c ] diff --git a/queue-2.6.28/bridge-bad-error-handling-when-adding-invalid-ether-address.patch b/queue-2.6.28/bridge-bad-error-handling-when-adding-invalid-ether-address.patch index 631195a2942..91cf5ee6642 100644 --- a/queue-2.6.28/bridge-bad-error-handling-when-adding-invalid-ether-address.patch +++ b/queue-2.6.28/bridge-bad-error-handling-when-adding-invalid-ether-address.patch @@ -3,6 +3,7 @@ From: Stephen Hemminger Date: Wed, 25 Mar 2009 21:01:47 -0700 Subject: bridge: bad error handling when adding invalid ether address +From: Stephen Hemminger [ Upstream commit cda6d377ec6b2ee2e58d563d0bd7eb313e0165df ] diff --git a/queue-2.6.28/ipv6-don-t-use-tw-net-when-accounting-for-recycled-tw.patch b/queue-2.6.28/ipv6-don-t-use-tw-net-when-accounting-for-recycled-tw.patch index 364524250b7..9c3baafbb9a 100644 --- a/queue-2.6.28/ipv6-don-t-use-tw-net-when-accounting-for-recycled-tw.patch +++ b/queue-2.6.28/ipv6-don-t-use-tw-net-when-accounting-for-recycled-tw.patch @@ -3,6 +3,7 @@ From: Pavel Emelyanov Date: Thu, 26 Feb 2009 03:35:13 -0800 Subject: ipv6: don't use tw net when accounting for recycled tw +From: Pavel Emelyanov [ Upstream commit 3f53a38131a4e7a053c0aa060aba0411242fb6b9 ] diff --git a/queue-2.6.28/ipv6-plug-sk_buff-leak-in-ipv6_rcv.patch b/queue-2.6.28/ipv6-plug-sk_buff-leak-in-ipv6_rcv.patch index 3123bc707d8..62f5df48cd1 100644 --- a/queue-2.6.28/ipv6-plug-sk_buff-leak-in-ipv6_rcv.patch +++ b/queue-2.6.28/ipv6-plug-sk_buff-leak-in-ipv6_rcv.patch @@ -3,6 +3,7 @@ From: Jesper Nilsson Date: Fri, 27 Mar 2009 00:17:45 -0700 Subject: ipv6: Plug sk_buff leak in ipv6_rcv (net/ipv6/ip6_input.c) +From: Jesper Nilsson [ Upstream commit 71f6f6dfdf7c7a67462386d9ea05c1095a89c555 ] diff --git a/queue-2.6.28/kprobes-fix-locking-imbalance-in-kretprobes.patch b/queue-2.6.28/kprobes-fix-locking-imbalance-in-kretprobes.patch new file mode 100644 index 00000000000..3788a25551c --- /dev/null +++ b/queue-2.6.28/kprobes-fix-locking-imbalance-in-kretprobes.patch @@ -0,0 +1,87 @@ +From f02b8624fedca39886b0eef770dca70c2f0749b3 Mon Sep 17 00:00:00 2001 +From: Ananth N Mavinakayanahalli +Date: Wed, 18 Mar 2009 17:06:21 +0530 +Subject: kprobes: Fix locking imbalance in kretprobes + +From: Ananth N Mavinakayanahalli + +commit f02b8624fedca39886b0eef770dca70c2f0749b3 upstream. + +Fix locking imbalance in kretprobes: + +===================================== +[ BUG: bad unlock balance detected! ] +------------------------------------- +kthreadd/2 is trying to release lock (&rp->lock) at: +[] pre_handler_kretprobe+0xea/0xf4 +but there are no more locks to release! + +other info that might help us debug this: +1 lock held by kthreadd/2: + #0: (rcu_read_lock){..--}, at: [] __atomic_notifier_call_chain+0x0/0x5a + +stack backtrace: +Pid: 2, comm: kthreadd Not tainted 2.6.29-rc8 #1 +Call Trace: + [] ? printk+0xf/0x17 + [] ? pre_handler_kretprobe+0xea/0xf4 + [] print_unlock_inbalance_bug+0xc3/0xce + [] ? clocksource_read+0x7/0xa + [] ? getnstimeofday+0x5f/0xf6 + [] ? register_lock_class+0x17/0x293 + [] ? mark_lock+0x1e/0x30b + [] ? tick_dev_program_event+0x4a/0xbc + [] ? __slab_alloc+0xa5/0x415 + [] ? pre_handler_kretprobe+0x28/0xf4 + [] ? pre_handler_kretprobe+0xea/0xf4 + [] lock_release_non_nested+0xa4/0x1a5 + [] ? pre_handler_kretprobe+0xea/0xf4 + [] lock_release+0x141/0x166 + [] _spin_unlock_irqrestore+0x19/0x50 + [] pre_handler_kretprobe+0xea/0xf4 + [] kprobe_exceptions_notify+0x1c9/0x43e + [] notifier_call_chain+0x26/0x48 + [] __atomic_notifier_call_chain+0x37/0x5a + [] ? __atomic_notifier_call_chain+0x0/0x5a + [] atomic_notifier_call_chain+0xc/0xe + [] notify_die+0x2d/0x2f + [] do_int3+0x1f/0x71 + [] int3+0x2c/0x34 + [] ? do_fork+0x1/0x288 + [] ? kernel_thread+0x71/0x79 + [] ? kthread+0x0/0x60 + [] ? kthread+0x0/0x60 + [] ? kernel_thread_helper+0x0/0x10 + [] kthreadd+0xac/0x148 + [] ? kthreadd+0x0/0x148 + [] kernel_thread_helper+0x7/0x10 + +Signed-off-by: Ananth N Mavinakayanahalli +Tested-by: Bharata B Rao +Cc: Masami Hiramatsu +Cc: Jim Keniston +Cc: Linus Torvalds +Cc: Andrew Morton +Cc: [2.6.29.x, 2.6.28.x, 2.6.27.x] +LKML-Reference: <20090318113621.GB4129@in.ibm.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/kprobes.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -901,10 +901,8 @@ static int __kprobes pre_handler_kretpro + ri->rp = rp; + ri->task = current; + +- if (rp->entry_handler && rp->entry_handler(ri, regs)) { +- spin_unlock_irqrestore(&rp->lock, flags); ++ if (rp->entry_handler && rp->entry_handler(ri, regs)) + return 0; +- } + + arch_prepare_kretprobe(ri, regs); + diff --git a/queue-2.6.28/net-fix-sctp-breakage.patch b/queue-2.6.28/net-fix-sctp-breakage.patch index 382be622ade..a4a6704dfea 100644 --- a/queue-2.6.28/net-fix-sctp-breakage.patch +++ b/queue-2.6.28/net-fix-sctp-breakage.patch @@ -3,6 +3,7 @@ From: Al Viro Date: Wed, 18 Mar 2009 19:12:42 -0700 Subject: net: fix sctp breakage +From: Al Viro [ Upstream commit cb0dc77de0d23615a845e45844a2e22fc224d7fe ] diff --git a/queue-2.6.28/netfilter-nf_conntrack_tcp-fix-unaligned-memory-access-in-tcp_sack.patch b/queue-2.6.28/netfilter-nf_conntrack_tcp-fix-unaligned-memory-access-in-tcp_sack.patch index 24e25f03aaf..35a1c824c98 100644 --- a/queue-2.6.28/netfilter-nf_conntrack_tcp-fix-unaligned-memory-access-in-tcp_sack.patch +++ b/queue-2.6.28/netfilter-nf_conntrack_tcp-fix-unaligned-memory-access-in-tcp_sack.patch @@ -3,6 +3,7 @@ From: Mark H. Weaver Date: Mon, 23 Mar 2009 13:46:12 +0100 Subject: netfilter: nf_conntrack_tcp: fix unaligned memory access in tcp_sack +From: Mark H. Weaver [ Upstream commit 534f81a5068799799e264fd162e9488a129f98d4 ] diff --git a/queue-2.6.28/series b/queue-2.6.28/series index 92513c380aa..c44e4327931 100644 --- a/queue-2.6.28/series +++ b/queue-2.6.28/series @@ -17,3 +17,36 @@ bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch 0032-Add-a-missing-unlock_kernel-in-raw_open.patch 0033-x86-PAT-PCI-Change-vma-prot-in-pci_mmap-to-reflec.patch 0037-x86-mtrr-don-t-modify-RdDram-WrDram-bits-of-fixed.patch +0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch +0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch +0013-dock-fix-dereference-after-kfree.patch +0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch +0031-mm-do_xip_mapping_read-fix-length-calculation.patch +0034-vfs-skip-I_CLEAR-state-inodes.patch +0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch +0044-net-netrom-Fix-socket-locking.patch +kprobes-fix-locking-imbalance-in-kretprobes.patch +0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch +0049-splice-fix-deadlock-in-splicing-to-file.patch +0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch +0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch +0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch +0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch +0060-sched-do-not-count-frozen-tasks-toward-load.patch +0063-add-some-long-missing-capabilities-to-fs_mask.patch +0064-spi-spi_write_then_read-bugfixes.patch +0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch +0069-hpt366-fix-HPT370-DMA-timeouts.patch +0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch +0071-mm-pass-correct-mm-when-growing-stack.patch +0072-SCSI-sg-fix-races-during-device-removal.patch +0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch +0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch +0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch +0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch +0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch +0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch +0090-Input-gameport-fix-attach-driver-code.patch +0024-r8169-Reset-IntrStatus-after-chip-reset.patch +0093-agp-zero-pages-before-sending-to-userspace.patch +0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch diff --git a/queue-2.6.28/xfrm-spin_lock-should-be-spin_unlock-in-xfrm_state.c.patch b/queue-2.6.28/xfrm-spin_lock-should-be-spin_unlock-in-xfrm_state.c.patch index f221d5aa107..0e2616fdfc1 100644 --- a/queue-2.6.28/xfrm-spin_lock-should-be-spin_unlock-in-xfrm_state.c.patch +++ b/queue-2.6.28/xfrm-spin_lock-should-be-spin_unlock-in-xfrm_state.c.patch @@ -3,6 +3,7 @@ From: Chuck Ebbert Date: Fri, 27 Mar 2009 00:22:01 -0700 Subject: xfrm: spin_lock() should be spin_unlock() in xfrm_state.c +From: Chuck Ebbert [ Upstream commit 7d0b591c655ca0d72ebcbd242cf659a20a8995c5 ]