From 3bfa2eb870bb8be4ba71680d2fd8b82b2854dc01 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 6 Jun 2007 12:49:14 -0700 Subject: [PATCH] more 2.6.21 patches added --- .../aacraid-correct-sa-platform-support.patch | 85 +++++++++++++ ...ntial-call-to-a-freed-memory-section.patch | 75 ++++++++++++ ...hutdown-while-device-is-still-active.patch | 104 ++++++++++++++++ ...able-polling-in-open-kernel-2.6.21.1.patch | 43 +++++++ queue-2.6.21/series | 6 + ...nrs-in-s_ino-to-avoid-readdir-oopses.patch | 114 ++++++++++++++++++ ...t-interrupt-interval-in-usb_bulk_msg.patch | 39 ++++++ 7 files changed, 466 insertions(+) create mode 100644 queue-2.6.21/aacraid-correct-sa-platform-support.patch create mode 100644 queue-2.6.21/acpi-fix-potential-call-to-a-freed-memory-section.patch create mode 100644 queue-2.6.21/cciss-fix-pci_driver.shutdown-while-device-is-still-active.patch create mode 100644 queue-2.6.21/e1000-don-t-enable-polling-in-open-kernel-2.6.21.1.patch create mode 100644 queue-2.6.21/sysfs-store-sysfs-inode-nrs-in-s_ino-to-avoid-readdir-oopses.patch create mode 100644 queue-2.6.21/usb-set-the-correct-interrupt-interval-in-usb_bulk_msg.patch diff --git a/queue-2.6.21/aacraid-correct-sa-platform-support.patch b/queue-2.6.21/aacraid-correct-sa-platform-support.patch new file mode 100644 index 00000000000..8797aaa1c0d --- /dev/null +++ b/queue-2.6.21/aacraid-correct-sa-platform-support.patch @@ -0,0 +1,85 @@ +From 2ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5 Mon Sep 17 00:00:00 2001 +From: Salyzyn, Mark +Date: Tue, 15 May 2007 09:14:21 -0400 +Cc: James Bottomley +Subject: SCSI: aacraid: Correct sa platform support. (Was: [Bug 8469] Bad EIP value on pentium3 SMP kernel-2.6.21.1) + + +http://bugzilla.kernel.org/show_bug.cgi?id=8469 + +As discussed in the bugzilla outlined below, we have an sa based +(Mustang) RAID adapter on the system, a Dell PERC2/QC. Affected +controllers are HP NetRAID, Adaptec AAC-364, Dell PERC2/QC or Adaptec +5400S. This problem coincides with the introduction of the adapter_comm +and adapter_deliver platform functions (Message [PATCH 1/4] aacraid: +rework communication support code, January 23 2007, which initially +migrated to 2.6.21) + +The panic occurs with an uninitialized adapter_deliver platform function +pointer. The enclosed patch, unmodified as tested by Rainer, solves the +problem. + +Signed-off-by: Mark Salyzyn +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/aacraid/aacraid.h | 1 + + drivers/scsi/aacraid/rx.c | 2 +- + drivers/scsi/aacraid/sa.c | 9 ++++++++- + 3 files changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/aacraid/aacraid.h ++++ b/drivers/scsi/aacraid/aacraid.h +@@ -1840,6 +1840,7 @@ struct aac_driver_ident* aac_get_driver_ + int aac_get_adapter_info(struct aac_dev* dev); + int aac_send_shutdown(struct aac_dev *dev); + int aac_probe_container(struct aac_dev *dev, int cid); ++int aac_rx_deliver_producer(struct fib * fib); + extern int numacb; + extern int acbsize; + extern char aac_driver_version[]; +--- a/drivers/scsi/aacraid/rx.c ++++ b/drivers/scsi/aacraid/rx.c +@@ -378,7 +378,7 @@ static int aac_rx_check_health(struct aa + * + * Will send a fib, returning 0 if successful. + */ +-static int aac_rx_deliver_producer(struct fib * fib) ++int aac_rx_deliver_producer(struct fib * fib) + { + struct aac_dev *dev = fib->dev; + struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; +--- a/drivers/scsi/aacraid/sa.c ++++ b/drivers/scsi/aacraid/sa.c +@@ -5,7 +5,7 @@ + * based on the old aacraid driver that is.. + * Adaptec aacraid device driver for Linux. + * +- * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) ++ * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -258,6 +258,11 @@ static void aac_sa_start_adapter(struct + NULL, NULL, NULL, NULL, NULL); + } + ++static int aac_sa_restart_adapter(struct aac_dev *dev, int bled) ++{ ++ return -EINVAL; ++} ++ + /** + * aac_sa_check_health + * @dev: device to check if healthy +@@ -367,7 +372,9 @@ int aac_sa_init(struct aac_dev *dev) + dev->a_ops.adapter_notify = aac_sa_notify_adapter; + dev->a_ops.adapter_sync_cmd = sa_sync_cmd; + dev->a_ops.adapter_check_health = aac_sa_check_health; ++ dev->a_ops.adapter_restart = aac_sa_restart_adapter; + dev->a_ops.adapter_intr = aac_sa_intr; ++ dev->a_ops.adapter_deliver = aac_rx_deliver_producer; + dev->a_ops.adapter_ioremap = aac_sa_ioremap; + + /* diff --git a/queue-2.6.21/acpi-fix-potential-call-to-a-freed-memory-section.patch b/queue-2.6.21/acpi-fix-potential-call-to-a-freed-memory-section.patch new file mode 100644 index 00000000000..c948bd6f6fe --- /dev/null +++ b/queue-2.6.21/acpi-fix-potential-call-to-a-freed-memory-section.patch @@ -0,0 +1,75 @@ +From stable-bounces@linux.kernel.org Wed May 16 22:15:15 2007 +From: Aaron Durbin +Date: Wed, 16 May 2007 22:11:06 -0700 +Subject: acpi: fix potential call to a freed memory section. +To: torvalds@linux-foundation.org +Cc: adurbin@google.com, akpm@linux-foundation.org, stable@kernel.org, lenb@kernel.org +Message-ID: <200705170511.l4H5B5kn017848@shell0.pdx.osdl.net> + + +From: Aaron Durbin + +Strip __cpuinit[data] from Node <-> PXM routines and supporting data +structures. Also make pxm_to_node_map and node_to_pxm_map local to the +numa acpi module. + +This fixes a bug triggered by the following conditions: +- boot on a machine with a SLIT table defined +- kernel is configured w/ CONFIG_HOTPLUG_CPU=n +- cat /sys/devices/system/node/node*/distance +This will cause an oops by calling into a freed memory section. + +In particular, on x86_64, __node_distance calls node_to_pxm(). + +Signed-off-by: Aaron Durbin +Cc: Len Brown +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/numa.c | 8 ++++---- + include/acpi/acpi_numa.h | 7 ++----- + 2 files changed, 6 insertions(+), 9 deletions(-) + +--- a/drivers/acpi/numa.c ++++ b/drivers/acpi/numa.c +@@ -40,19 +40,19 @@ static nodemask_t nodes_found_map = NODE + #define NID_INVAL -1 + + /* maps to convert between proximity domain and logical node ID */ +-int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS] ++static int pxm_to_node_map[MAX_PXM_DOMAINS] + = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL }; +-int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] ++static int node_to_pxm_map[MAX_NUMNODES] + = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; + +-int __cpuinit pxm_to_node(int pxm) ++int pxm_to_node(int pxm) + { + if (pxm < 0) + return NID_INVAL; + return pxm_to_node_map[pxm]; + } + +-int __cpuinit node_to_pxm(int node) ++int node_to_pxm(int node) + { + if (node < 0) + return PXM_INVAL; +--- a/include/acpi/acpi_numa.h ++++ b/include/acpi/acpi_numa.h +@@ -11,11 +11,8 @@ + #define MAX_PXM_DOMAINS (256) /* Old pxm spec is defined 8 bit */ + #endif + +-extern int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]; +-extern int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]; +- +-extern int __cpuinit pxm_to_node(int); +-extern int __cpuinit node_to_pxm(int); ++extern int pxm_to_node(int); ++extern int node_to_pxm(int); + extern int __cpuinit acpi_map_pxm_to_node(int); + extern void __cpuinit acpi_unmap_pxm_to_node(int); + diff --git a/queue-2.6.21/cciss-fix-pci_driver.shutdown-while-device-is-still-active.patch b/queue-2.6.21/cciss-fix-pci_driver.shutdown-while-device-is-still-active.patch new file mode 100644 index 00000000000..fee122bdd49 --- /dev/null +++ b/queue-2.6.21/cciss-fix-pci_driver.shutdown-while-device-is-still-active.patch @@ -0,0 +1,104 @@ +From stable-bounces@linux.kernel.org Sat May 19 10:21:58 2007 +From: Gerald Britton +Date: Sat, 19 May 2007 10:18:22 -0700 +Subject: cciss: fix pci_driver.shutdown while device is still active +To: gbritton@alum.mit.edu, mike.miller@hp.com, stable@kernel.org, mm-commits@vger.kernel.org +Message-ID: <200705191718.l4JHILKW007005@shell0.pdx.osdl.net> + +From: Gerald Britton + +Fix an Oops in the cciss driver caused by system shutdown while a +filesystem on a cciss device is still active. The cciss_remove_one +function only properly removes the device if the device has been cleanly +released by its users, which is not the case when the pci_driver.shutdown +method is called. + +This patch adds a new cciss_shutdown function to better match the pattern +used by various SCSI drivers: deactivate device interrupts and flush +caches. It also alters the cciss_remove_one function to match and readds +the __devexit annotation that was removed when cciss_remove_one was serving +as the pci_driver.shutdown method. + +Signed-off-by: Gerald Britton +Acked-by: Mike Miller +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/block/cciss.c | 45 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 30 insertions(+), 15 deletions(-) + +--- a/drivers/block/cciss.c ++++ b/drivers/block/cciss.c +@@ -3405,13 +3405,39 @@ static int __devinit cciss_init_one(stru + return -1; + } + +-static void cciss_remove_one(struct pci_dev *pdev) ++static void cciss_shutdown(struct pci_dev *pdev) + { + ctlr_info_t *tmp_ptr; +- int i, j; ++ int i; + char flush_buf[4]; + int return_code; + ++ tmp_ptr = pci_get_drvdata(pdev); ++ if (tmp_ptr == NULL) ++ return; ++ i = tmp_ptr->ctlr; ++ if (hba[i] == NULL) ++ return; ++ ++ /* Turn board interrupts off and send the flush cache command */ ++ /* sendcmd will turn off interrupt, and send the flush... ++ * To write all data in the battery backed cache to disks */ ++ memset(flush_buf, 0, 4); ++ return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL, ++ TYPE_CMD); ++ if (return_code == IO_OK) { ++ printk(KERN_INFO "Completed flushing cache on controller %d\n", i); ++ } else { ++ printk(KERN_WARNING "Error flushing cache on controller %d\n", i); ++ } ++ free_irq(hba[i]->intr[2], hba[i]); ++} ++ ++static void __devexit cciss_remove_one(struct pci_dev *pdev) ++{ ++ ctlr_info_t *tmp_ptr; ++ int i, j; ++ + if (pci_get_drvdata(pdev) == NULL) { + printk(KERN_ERR "cciss: Unable to remove device \n"); + return; +@@ -3442,18 +3468,7 @@ static void cciss_remove_one(struct pci_ + + cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ + +- /* Turn board interrupts off and send the flush cache command */ +- /* sendcmd will turn off interrupt, and send the flush... +- * To write all data in the battery backed cache to disks */ +- memset(flush_buf, 0, 4); +- return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL, +- TYPE_CMD); +- if (return_code == IO_OK) { +- printk(KERN_INFO "Completed flushing cache on controller %d\n", i); +- } else { +- printk(KERN_WARNING "Error flushing cache on controller %d\n", i); +- } +- free_irq(hba[i]->intr[2], hba[i]); ++ cciss_shutdown(pdev); + + #ifdef CONFIG_PCI_MSI + if (hba[i]->msix_vector) +@@ -3486,7 +3501,7 @@ static struct pci_driver cciss_pci_drive + .probe = cciss_init_one, + .remove = __devexit_p(cciss_remove_one), + .id_table = cciss_pci_device_id, /* id_table */ +- .shutdown = cciss_remove_one, ++ .shutdown = cciss_shutdown, + }; + + /* diff --git a/queue-2.6.21/e1000-don-t-enable-polling-in-open-kernel-2.6.21.1.patch b/queue-2.6.21/e1000-don-t-enable-polling-in-open-kernel-2.6.21.1.patch new file mode 100644 index 00000000000..8d8c61eec8e --- /dev/null +++ b/queue-2.6.21/e1000-don-t-enable-polling-in-open-kernel-2.6.21.1.patch @@ -0,0 +1,43 @@ +From stable-bounces@linux.kernel.org Mon May 21 14:57:32 2007 +From: Auke Kok +Date: Mon, 21 May 2007 14:55:36 -0700 +Subject: e1000: Don't enable polling in open() (was: e1000: assertion hit in e1000_clean(), kernel 2.6.21.1)] +To: stable@kernel.org, Greg KH +Message-ID: <46521558.2010309@intel.com> + +From: Auke Kok + +Herbert Xu wrote: +"netif_poll_enable can only be called if you've previously called +netif_poll_disable. Otherwise a poll might already be in action +and you may get a crash like this." + +Removing the call to netif_poll_enable in e1000_open should fix this issue, +the only other call to netif_poll_enable is in e1000_up() which is only +reached after a device reset or resume. + +Bugzilla: http://bugzilla.kernel.org/show_bug.cgi?id=8455 +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=240339 + +Tested by Doug Chapman + +Signed-off-by: Auke Kok +Acked-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/e1000/e1000_main.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/net/e1000/e1000_main.c ++++ b/drivers/net/e1000/e1000_main.c +@@ -549,9 +549,6 @@ e1000_up(struct e1000_adapter *adapter) + + adapter->tx_queue_len = netdev->tx_queue_len; + +-#ifdef CONFIG_E1000_NAPI +- netif_poll_enable(netdev); +-#endif + e1000_irq_enable(adapter); + + clear_bit(__E1000_DOWN, &adapter->flags); diff --git a/queue-2.6.21/series b/queue-2.6.21/series index e84dfcaeb22..071afb6c2e4 100644 --- a/queue-2.6.21/series +++ b/queue-2.6.21/series @@ -32,3 +32,9 @@ tg3-fix-link-problem-on-dell-s-onboard-5906.patch uml-improve-host-ptrace_sysemu-check.patch x86-fix-oprofile-double-free.patch fix-roundup_pow_of_two.patch +usb-set-the-correct-interrupt-interval-in-usb_bulk_msg.patch +acpi-fix-potential-call-to-a-freed-memory-section.patch +aacraid-correct-sa-platform-support.patch +cciss-fix-pci_driver.shutdown-while-device-is-still-active.patch +sysfs-store-sysfs-inode-nrs-in-s_ino-to-avoid-readdir-oopses.patch +e1000-don-t-enable-polling-in-open-kernel-2.6.21.1.patch diff --git a/queue-2.6.21/sysfs-store-sysfs-inode-nrs-in-s_ino-to-avoid-readdir-oopses.patch b/queue-2.6.21/sysfs-store-sysfs-inode-nrs-in-s_ino-to-avoid-readdir-oopses.patch new file mode 100644 index 00000000000..6f9d92e7fd3 --- /dev/null +++ b/queue-2.6.21/sysfs-store-sysfs-inode-nrs-in-s_ino-to-avoid-readdir-oopses.patch @@ -0,0 +1,114 @@ +From stable-bounces@linux.kernel.org Mon May 21 19:34:01 2007 +From: Eric Sandeen +Date: Mon, 21 May 2007 21:32:40 -0500 +Subject: sysfs: store sysfs inode nrs in s_ino to avoid readdir oopses +To: Eric Sandeen +Cc: stable@kernel.org, Andrew Morton , Tejun Heo , Linux Kernel Mailing List , Maneesh Soni +Message-ID: <46525648.8050807@sandeen.net> + + +Backport of +ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.22-rc1/2.6.22-rc1-mm1/broken-out/gregkh-driver-sysfs-allocate-inode-number-using-ida.patch + +For regular files in sysfs, sysfs_readdir wants to traverse +sysfs_dirent->s_dentry->d_inode->i_ino to get to the inode number. +But, the dentry can be reclaimed under memory pressure, and there +is no synchronization with readdir. This patch follows Tejun's +scheme of allocating and storing an inode number in the new s_ino +member of a sysfs_dirent, when dirents are created, and retrieving +it from there for readdir, so that the pointer chain doesn't have +to be traversed. + +Tejun's upstream patch uses a new-ish "ida" allocator which brings along +some extra complexity; this -stable patch has a brain-dead incrementing +counter which does not guarantee uniqueness, but because sysfs doesn't +hash inodes as iunique expects, uniqueness wasn't guaranteed today anyway. + +Signed-off-by: Eric Sandeen +Cc: Tejun Heo +Cc: Maneesh Soni +Signed-off-by: Greg Kroah-Hartman + +--- + fs/sysfs/dir.c | 16 +++++++++++----- + fs/sysfs/inode.c | 1 + + fs/sysfs/mount.c | 1 + + fs/sysfs/sysfs.h | 1 + + 4 files changed, 14 insertions(+), 5 deletions(-) + +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -30,6 +30,14 @@ static struct dentry_operations sysfs_de + .d_iput = sysfs_d_iput, + }; + ++static unsigned int sysfs_inode_counter; ++ino_t sysfs_get_inum(void) ++{ ++ if (unlikely(sysfs_inode_counter < 3)) ++ sysfs_inode_counter = 3; ++ return sysfs_inode_counter++; ++} ++ + /* + * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent + */ +@@ -41,6 +49,7 @@ static struct sysfs_dirent * __sysfs_new + if (!sd) + return NULL; + ++ sd->s_ino = sysfs_get_inum(); + atomic_set(&sd->s_count, 1); + atomic_set(&sd->s_event, 1); + INIT_LIST_HEAD(&sd->s_children); +@@ -509,7 +518,7 @@ static int sysfs_readdir(struct file * f + + switch (i) { + case 0: +- ino = dentry->d_inode->i_ino; ++ ino = parent_sd->s_ino; + if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) + break; + filp->f_pos++; +@@ -538,10 +547,7 @@ static int sysfs_readdir(struct file * f + + name = sysfs_get_name(next); + len = strlen(name); +- if (next->s_dentry) +- ino = next->s_dentry->d_inode->i_ino; +- else +- ino = iunique(sysfs_sb, 2); ++ ino = next->s_ino; + + if (filldir(dirent, name, len, filp->f_pos, ino, + dt_type(next)) < 0) +--- a/fs/sysfs/inode.c ++++ b/fs/sysfs/inode.c +@@ -140,6 +140,7 @@ struct inode * sysfs_new_inode(mode_t mo + inode->i_mapping->a_ops = &sysfs_aops; + inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; + inode->i_op = &sysfs_inode_operations; ++ inode->i_ino = sd->s_ino; + lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); + + if (sd->s_iattr) { +--- a/fs/sysfs/mount.c ++++ b/fs/sysfs/mount.c +@@ -33,6 +33,7 @@ static struct sysfs_dirent sysfs_root = + .s_element = NULL, + .s_type = SYSFS_ROOT, + .s_iattr = NULL, ++ .s_ino = 1, + }; + + static void sysfs_clear_inode(struct inode *inode) +--- a/fs/sysfs/sysfs.h ++++ b/fs/sysfs/sysfs.h +@@ -5,6 +5,7 @@ struct sysfs_dirent { + void * s_element; + int s_type; + umode_t s_mode; ++ ino_t s_ino; + struct dentry * s_dentry; + struct iattr * s_iattr; + atomic_t s_event; diff --git a/queue-2.6.21/usb-set-the-correct-interrupt-interval-in-usb_bulk_msg.patch b/queue-2.6.21/usb-set-the-correct-interrupt-interval-in-usb_bulk_msg.patch new file mode 100644 index 00000000000..9623e0e3af9 --- /dev/null +++ b/queue-2.6.21/usb-set-the-correct-interrupt-interval-in-usb_bulk_msg.patch @@ -0,0 +1,39 @@ +From stable-bounces@linux.kernel.org Fri Apr 27 11:34:08 2007 +From: Alan Stern +Date: Fri, 27 Apr 2007 14:32:47 -0400 (EDT) +Subject: USB: set the correct Interrupt interval in usb_bulk_msg +To: stable@kernel.org +Message-ID: + + +This patch (as902) fixes a mistake I introduced into usb_bulk_msg(). +usb_fill_int_urb() already does the bit-shifting calculation for +high-speed Interrupt intervals; it shouldn't be done twice. + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/message.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -221,15 +221,10 @@ int usb_bulk_msg(struct usb_device *usb_ + + if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) { +- int interval; +- +- if (usb_dev->speed == USB_SPEED_HIGH) +- interval = 1 << min(15, ep->desc.bInterval - 1); +- else +- interval = ep->desc.bInterval; + pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); + usb_fill_int_urb(urb, usb_dev, pipe, data, len, +- usb_api_blocking_completion, NULL, interval); ++ usb_api_blocking_completion, NULL, ++ ep->desc.bInterval); + } else + usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, + usb_api_blocking_completion, NULL); -- 2.47.3