]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.2-stable patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 10 Jan 2012 00:33:25 +0000 (16:33 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 10 Jan 2012 00:33:25 +0000 (16:33 -0800)
added patches:
atmel_serial-fix-spinlock-lockup-in-rs485-code.patch
cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch
drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch
drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch
drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch
ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch
ib-qib-fix-a-possible-data-corruption-when-receiving.patch
ib-uverbs-protect-qp-multicast-list.patch
iwlagn-fix-remove-use-of-page_size.patch
iwlagn-fix-tid-use-bug.patch
ore-fix-breakage-when-misc_filesystems-is-not-set.patch
ore-fix-bug_on-too-few-sgs-when-reading.patch
ore-fix-crash-in-case-of-an-io-error.patch
ore-must-support-none-page-aligned-io.patch
perf-fix-parsing-of-__print_flags-in-tp_printk.patch
reiserfs-fix-quota-mount-option-parsing.patch
reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch
udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch
usbfs-fix-oops-related-to-user-namespace-conversion.patch
usb-isight-fix-kernel-bug-when-loading-firmware.patch
usb-update-documentation-for-usbmon.patch

22 files changed:
queue-3.2/atmel_serial-fix-spinlock-lockup-in-rs485-code.patch [new file with mode: 0644]
queue-3.2/cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch [new file with mode: 0644]
queue-3.2/drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch [new file with mode: 0644]
queue-3.2/drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch [new file with mode: 0644]
queue-3.2/drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch [new file with mode: 0644]
queue-3.2/ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch [new file with mode: 0644]
queue-3.2/ib-qib-fix-a-possible-data-corruption-when-receiving.patch [new file with mode: 0644]
queue-3.2/ib-uverbs-protect-qp-multicast-list.patch [new file with mode: 0644]
queue-3.2/iwlagn-fix-remove-use-of-page_size.patch [new file with mode: 0644]
queue-3.2/iwlagn-fix-tid-use-bug.patch [new file with mode: 0644]
queue-3.2/ore-fix-breakage-when-misc_filesystems-is-not-set.patch [new file with mode: 0644]
queue-3.2/ore-fix-bug_on-too-few-sgs-when-reading.patch [new file with mode: 0644]
queue-3.2/ore-fix-crash-in-case-of-an-io-error.patch [new file with mode: 0644]
queue-3.2/ore-must-support-none-page-aligned-io.patch [new file with mode: 0644]
queue-3.2/perf-fix-parsing-of-__print_flags-in-tp_printk.patch [new file with mode: 0644]
queue-3.2/reiserfs-fix-quota-mount-option-parsing.patch [new file with mode: 0644]
queue-3.2/reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch [new file with mode: 0644]
queue-3.2/series
queue-3.2/udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch [new file with mode: 0644]
queue-3.2/usb-isight-fix-kernel-bug-when-loading-firmware.patch [new file with mode: 0644]
queue-3.2/usb-update-documentation-for-usbmon.patch [new file with mode: 0644]
queue-3.2/usbfs-fix-oops-related-to-user-namespace-conversion.patch [new file with mode: 0644]

diff --git a/queue-3.2/atmel_serial-fix-spinlock-lockup-in-rs485-code.patch b/queue-3.2/atmel_serial-fix-spinlock-lockup-in-rs485-code.patch
new file mode 100644 (file)
index 0000000..2066109
--- /dev/null
@@ -0,0 +1,45 @@
+From dbf1115d3f8c7052788aa4e6e46abd27f3b3eeba Mon Sep 17 00:00:00 2001
+From: Claudio Scordino <claudio@evidence.eu.com>
+Date: Fri, 16 Dec 2011 15:08:49 +0100
+Subject: atmel_serial: fix spinlock lockup in RS485 code
+
+From: Claudio Scordino <claudio@evidence.eu.com>
+
+commit dbf1115d3f8c7052788aa4e6e46abd27f3b3eeba upstream.
+
+Patch to fix a spinlock lockup in the driver that sometimes happens when the
+tasklet starts.
+
+Signed-off-by: Claudio Scordino <claudio@evidence.eu.com>
+Signed-off-by: Dave Bender <codehero@gmail.com>
+Tested-by: Dave Bender <codehero@gmail.com>
+Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/serial/atmel_serial.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -212,8 +212,9 @@ void atmel_config_rs485(struct uart_port
+ {
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+       unsigned int mode;
++      unsigned long flags;
+-      spin_lock(&port->lock);
++      spin_lock_irqsave(&port->lock, flags);
+       /* Disable interrupts */
+       UART_PUT_IDR(port, atmel_port->tx_done_mask);
+@@ -244,7 +245,7 @@ void atmel_config_rs485(struct uart_port
+       /* Enable interrupts */
+       UART_PUT_IER(port, atmel_port->tx_done_mask);
+-      spin_unlock(&port->lock);
++      spin_unlock_irqrestore(&port->lock, flags);
+ }
diff --git a/queue-3.2/cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch b/queue-3.2/cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch
new file mode 100644 (file)
index 0000000..2dd8280
--- /dev/null
@@ -0,0 +1,48 @@
+From 0d19ea866562e46989412a0676412fa0983c9ce7 Mon Sep 17 00:00:00 2001
+From: Li Zefan <lizf@cn.fujitsu.com>
+Date: Tue, 27 Dec 2011 14:25:55 +0800
+Subject: cgroup: fix to allow mounting a hierarchy by name
+
+From: Li Zefan <lizf@cn.fujitsu.com>
+
+commit 0d19ea866562e46989412a0676412fa0983c9ce7 upstream.
+
+If we mount a hierarchy with a specified name, the name is unique,
+and we can use it to mount the hierarchy without specifying its
+set of subsystem names. This feature is documented is
+Documentation/cgroups/cgroups.txt section 2.3
+
+Here's an example:
+
+       # mount -t cgroup -o cpuset,name=myhier xxx /cgroup1
+       # mount -t cgroup -o name=myhier xxx /cgroup2
+
+But it was broken by commit 32a8cf235e2f192eb002755076994525cdbaa35a
+(cgroup: make the mount options parsing more accurate)
+
+This fixes the regression.
+
+Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/cgroup.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -1175,10 +1175,10 @@ static int parse_cgroupfs_options(char *
+       /*
+        * If the 'all' option was specified select all the subsystems,
+-       * otherwise 'all, 'none' and a subsystem name options were not
+-       * specified, let's default to 'all'
++       * otherwise if 'none', 'name=' and a subsystem name options
++       * were not specified, let's default to 'all'
+        */
+-      if (all_ss || (!all_ss && !one_ss && !opts->none)) {
++      if (all_ss || (!one_ss && !opts->none && !opts->name)) {
+               for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+                       struct cgroup_subsys *ss = subsys[i];
+                       if (ss == NULL)
diff --git a/queue-3.2/drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch b/queue-3.2/drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch
new file mode 100644 (file)
index 0000000..b565195
--- /dev/null
@@ -0,0 +1,68 @@
+From cf6a2eacbcb2593b5b91d0817915c4f0464bb534 Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Thu, 1 Dec 2011 09:59:34 -0800
+Subject: drivers: hv: Don't OOPS when you cannot init vmbus
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit cf6a2eacbcb2593b5b91d0817915c4f0464bb534 upstream.
+
+The hv vmbus driver was causing an OOPS since it was trying to register drivers
+on top of the bus even if initialization of the bus has failed for some
+reason (such as the odd chance someone would run a hv enabled kernel in a
+non-hv environment).
+
+Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hv/vmbus_drv.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -62,6 +62,14 @@ struct hv_device_info {
+       struct hv_dev_port_info outbound;
+ };
++static int vmbus_exists(void)
++{
++      if (hv_acpi_dev == NULL)
++              return -ENODEV;
++
++      return 0;
++}
++
+ static void get_channel_info(struct hv_device *device,
+                            struct hv_device_info *info)
+@@ -590,6 +598,10 @@ int __vmbus_driver_register(struct hv_dr
+       pr_info("registering driver %s\n", hv_driver->name);
++      ret = vmbus_exists();
++      if (ret < 0)
++              return ret;
++
+       hv_driver->driver.name = hv_driver->name;
+       hv_driver->driver.owner = owner;
+       hv_driver->driver.mod_name = mod_name;
+@@ -614,6 +626,9 @@ void vmbus_driver_unregister(struct hv_d
+ {
+       pr_info("unregistering driver %s\n", hv_driver->name);
++      if (!vmbus_exists())
++              return;
++
+       driver_unregister(&hv_driver->driver);
+ }
+@@ -776,6 +791,7 @@ static int __init hv_acpi_init(void)
+ cleanup:
+       acpi_bus_unregister_driver(&vmbus_acpi_driver);
++      hv_acpi_dev = NULL;
+       return ret;
+ }
diff --git a/queue-3.2/drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch b/queue-3.2/drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch
new file mode 100644 (file)
index 0000000..8b80154
--- /dev/null
@@ -0,0 +1,38 @@
+From 8f257a142fc3868d69de3f996b95d7bdbc509560 Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Tue, 27 Dec 2011 13:49:37 -0800
+Subject: Drivers:hv: Fix a bug in vmbus_driver_unregister()
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit 8f257a142fc3868d69de3f996b95d7bdbc509560 upstream.
+
+The function vmbus_exists() was introduced recently to deal with cases where
+the vmbus driver failed to initialize and yet other Hyper-V drivers attempted
+to register with the vmbus bus driver. This patch introduced a bug where
+vmbus_driver_unregister() would fail to unregister the driver. This patch
+fixes the problem.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Fuzhou Chen <fuzhouch@microsoft.com>
+Cc: Sasha Levin <levinsasha928@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hv/vmbus_drv.c |    5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -627,10 +627,7 @@ void vmbus_driver_unregister(struct hv_d
+       pr_info("unregistering driver %s\n", hv_driver->name);
+       if (!vmbus_exists())
+-              return;
+-
+-      driver_unregister(&hv_driver->driver);
+-
++              driver_unregister(&hv_driver->driver);
+ }
+ EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
diff --git a/queue-3.2/drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch b/queue-3.2/drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch
new file mode 100644 (file)
index 0000000..cf23662
--- /dev/null
@@ -0,0 +1,43 @@
+From e7c8e8605d0bafc705ff27f9da98a1668427cc0f Mon Sep 17 00:00:00 2001
+From: Julia Lawall <julia@diku.dk>
+Date: Fri, 23 Dec 2011 14:02:55 +0100
+Subject: drivers/usb/class/cdc-acm.c: clear dangling pointer
+
+From: Julia Lawall <julia@diku.dk>
+
+commit e7c8e8605d0bafc705ff27f9da98a1668427cc0f upstream.
+
+On some failures, the country_code field of an acm structure is freed
+without freeing the acm structure itself.  Elsewhere, operations including
+memcpy and kfree are performed on the country_code field.  The patch sets
+the country_code field to NULL when it is freed, and likewise sets the
+country_code_size field to 0.
+
+Signed-off-by: Julia Lawall <julia@diku.dk>
+Acked-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/class/cdc-acm.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1183,6 +1183,8 @@ made_compressed_probe:
+               i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
+               if (i < 0) {
+                       kfree(acm->country_codes);
++                      acm->country_codes = NULL;
++                      acm->country_code_size = 0;
+                       goto skip_countries;
+               }
+@@ -1191,6 +1193,8 @@ made_compressed_probe:
+               if (i < 0) {
+                       device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
+                       kfree(acm->country_codes);
++                      acm->country_codes = NULL;
++                      acm->country_code_size = 0;
+                       goto skip_countries;
+               }
+       }
diff --git a/queue-3.2/ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch b/queue-3.2/ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch
new file mode 100644 (file)
index 0000000..0eff459
--- /dev/null
@@ -0,0 +1,70 @@
+From 33c104d415e92a51aaf638dc3d93920cfa601e5c Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 22 Dec 2011 16:49:05 +0100
+Subject: ext3: Don't warn from writepage when readonly inode is spotted after error
+
+From: Jan Kara <jack@suse.cz>
+
+commit 33c104d415e92a51aaf638dc3d93920cfa601e5c upstream.
+
+WARN_ON_ONCE(IS_RDONLY(inode)) tends to trip when filesystem hits error and is
+remounted read-only. This unnecessarily scares users (well, they should be
+scared because of filesystem error, but the stack trace distracts them from the
+right source of their fear ;-). We could as well just remove the WARN_ON but
+it's not hard to fix it to not trip on filesystem with errors and not use more
+cycles in the common case so that's what we do.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext3/inode.c |   24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/fs/ext3/inode.c
++++ b/fs/ext3/inode.c
+@@ -1617,7 +1617,13 @@ static int ext3_ordered_writepage(struct
+       int err;
+       J_ASSERT(PageLocked(page));
+-      WARN_ON_ONCE(IS_RDONLY(inode));
++      /*
++       * We don't want to warn for emergency remount. The condition is
++       * ordered to avoid dereferencing inode->i_sb in non-error case to
++       * avoid slow-downs.
++       */
++      WARN_ON_ONCE(IS_RDONLY(inode) &&
++                   !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
+       /*
+        * We give up here if we're reentered, because it might be for a
+@@ -1692,7 +1698,13 @@ static int ext3_writeback_writepage(stru
+       int err;
+       J_ASSERT(PageLocked(page));
+-      WARN_ON_ONCE(IS_RDONLY(inode));
++      /*
++       * We don't want to warn for emergency remount. The condition is
++       * ordered to avoid dereferencing inode->i_sb in non-error case to
++       * avoid slow-downs.
++       */
++      WARN_ON_ONCE(IS_RDONLY(inode) &&
++                   !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
+       if (ext3_journal_current_handle())
+               goto out_fail;
+@@ -1735,7 +1747,13 @@ static int ext3_journalled_writepage(str
+       int err;
+       J_ASSERT(PageLocked(page));
+-      WARN_ON_ONCE(IS_RDONLY(inode));
++      /*
++       * We don't want to warn for emergency remount. The condition is
++       * ordered to avoid dereferencing inode->i_sb in non-error case to
++       * avoid slow-downs.
++       */
++      WARN_ON_ONCE(IS_RDONLY(inode) &&
++                   !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
+       if (ext3_journal_current_handle())
+               goto no_write;
diff --git a/queue-3.2/ib-qib-fix-a-possible-data-corruption-when-receiving.patch b/queue-3.2/ib-qib-fix-a-possible-data-corruption-when-receiving.patch
new file mode 100644 (file)
index 0000000..d9d9459
--- /dev/null
@@ -0,0 +1,72 @@
+From eddfb675256f49d14e8c5763098afe3eb2c93701 Mon Sep 17 00:00:00 2001
+From: Ram Vepa <ram.vepa@qlogic.com>
+Date: Fri, 23 Dec 2011 08:01:43 -0500
+Subject: IB/qib: Fix a possible data corruption when receiving
+ packets
+
+From: Ram Vepa <ram.vepa@qlogic.com>
+
+commit eddfb675256f49d14e8c5763098afe3eb2c93701 upstream.
+
+Prevent a receive data corruption by ensuring that the write to update
+the rcvhdrheadn register to generate an interrupt is at the very end
+of the receive processing.
+
+Signed-off-by: Ramkrishna Vepa <ram.vepa@qlogic.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/infiniband/hw/qib/qib_iba6120.c |    4 +++-
+ drivers/infiniband/hw/qib/qib_iba7220.c |    4 +++-
+ drivers/infiniband/hw/qib/qib_iba7322.c |    6 ++++--
+ 3 files changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/infiniband/hw/qib/qib_iba6120.c
++++ b/drivers/infiniband/hw/qib/qib_iba6120.c
+@@ -2076,9 +2076,11 @@ static void qib_6120_config_ctxts(struct
+ static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd,
+                                   u32 updegr, u32 egrhd, u32 npkts)
+ {
+-      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
+       if (updegr)
+               qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
++      mmiowb();
++      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
++      mmiowb();
+ }
+ static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd)
+--- a/drivers/infiniband/hw/qib/qib_iba7220.c
++++ b/drivers/infiniband/hw/qib/qib_iba7220.c
+@@ -2725,9 +2725,11 @@ static int qib_7220_set_loopback(struct
+ static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd,
+                                   u32 updegr, u32 egrhd, u32 npkts)
+ {
+-      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
+       if (updegr)
+               qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
++      mmiowb();
++      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
++      mmiowb();
+ }
+ static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd)
+--- a/drivers/infiniband/hw/qib/qib_iba7322.c
++++ b/drivers/infiniband/hw/qib/qib_iba7322.c
+@@ -4082,10 +4082,12 @@ static void qib_update_7322_usrhead(stru
+        */
+       if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT)
+               adjust_rcv_timeout(rcd, npkts);
+-      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
+-      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
+       if (updegr)
+               qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
++      mmiowb();
++      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
++      qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
++      mmiowb();
+ }
+ static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd)
diff --git a/queue-3.2/ib-uverbs-protect-qp-multicast-list.patch b/queue-3.2/ib-uverbs-protect-qp-multicast-list.patch
new file mode 100644 (file)
index 0000000..72129ca
--- /dev/null
@@ -0,0 +1,94 @@
+From e214a0fe2b382fa302c036ecd6e6ffe99e3b9875 Mon Sep 17 00:00:00 2001
+From: Eli Cohen <eli@dev.mellanox.co.il>
+Date: Tue, 3 Jan 2012 20:36:48 -0800
+Subject: IB/uverbs: Protect QP multicast list
+
+From: Eli Cohen <eli@dev.mellanox.co.il>
+
+commit e214a0fe2b382fa302c036ecd6e6ffe99e3b9875 upstream.
+
+Userspace verbs multicast attach/detach operations on a QP are done
+while holding the rwsem of the QP for reading.  That's not sufficient
+since a reader lock allows more than one reader to acquire the
+lock.  However, multicast attach/detach does list manipulation that
+can corrupt the list if multiple threads run in parallel.
+
+Fix this by acquiring the rwsem as a writer to serialize attach/detach
+operations.  Add idr_write_qp() and put_qp_write() to encapsulate
+this.
+
+This fixes oops seen when running applications that perform multicast
+joins/leaves.
+
+Reported by: Mike Dubman <miked@mellanox.com>
+Signed-off-by: Eli Cohen <eli@mellanox.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/infiniband/core/uverbs_cmd.c |   21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+--- a/drivers/infiniband/core/uverbs_cmd.c
++++ b/drivers/infiniband/core/uverbs_cmd.c
+@@ -241,11 +241,24 @@ static struct ib_qp *idr_read_qp(int qp_
+       return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0);
+ }
++static struct ib_qp *idr_write_qp(int qp_handle, struct ib_ucontext *context)
++{
++      struct ib_uobject *uobj;
++
++      uobj = idr_write_uobj(&ib_uverbs_qp_idr, qp_handle, context);
++      return uobj ? uobj->object : NULL;
++}
++
+ static void put_qp_read(struct ib_qp *qp)
+ {
+       put_uobj_read(qp->uobject);
+ }
++static void put_qp_write(struct ib_qp *qp)
++{
++      put_uobj_write(qp->uobject);
++}
++
+ static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context)
+ {
+       return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0);
+@@ -2375,7 +2388,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib
+       if (copy_from_user(&cmd, buf, sizeof cmd))
+               return -EFAULT;
+-      qp = idr_read_qp(cmd.qp_handle, file->ucontext);
++      qp = idr_write_qp(cmd.qp_handle, file->ucontext);
+       if (!qp)
+               return -EINVAL;
+@@ -2404,7 +2417,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib
+               kfree(mcast);
+ out_put:
+-      put_qp_read(qp);
++      put_qp_write(qp);
+       return ret ? ret : in_len;
+ }
+@@ -2422,7 +2435,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib
+       if (copy_from_user(&cmd, buf, sizeof cmd))
+               return -EFAULT;
+-      qp = idr_read_qp(cmd.qp_handle, file->ucontext);
++      qp = idr_write_qp(cmd.qp_handle, file->ucontext);
+       if (!qp)
+               return -EINVAL;
+@@ -2441,7 +2454,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib
+               }
+ out_put:
+-      put_qp_read(qp);
++      put_qp_write(qp);
+       return ret ? ret : in_len;
+ }
diff --git a/queue-3.2/iwlagn-fix-remove-use-of-page_size.patch b/queue-3.2/iwlagn-fix-remove-use-of-page_size.patch
new file mode 100644 (file)
index 0000000..ef78910
--- /dev/null
@@ -0,0 +1,178 @@
+From 106671369e6d046c0b3e1e72b18ad6dd9cb298b0 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Mon, 19 Dec 2011 14:00:59 -0800
+Subject: iwlagn: fix (remove) use of PAGE_SIZE
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 106671369e6d046c0b3e1e72b18ad6dd9cb298b0 upstream.
+
+The ICT code erroneously uses PAGE_SIZE. The bug
+is that PAGE_SIZE isn't necessarily 4096, so on
+such platforms this code will not work correctly
+as we'll try to attempt to read an index in the
+table that the device never wrote, it always has
+4096-byte pages.
+
+Additionally, the manual alignment code here is
+unnecessary -- Documentation/DMA-API-HOWTO.txt
+states:
+  The cpu return address and the DMA bus master address are both
+  guaranteed to be aligned to the smallest PAGE_SIZE order which
+  is greater than or equal to the requested size.  This invariant
+  exists (for example) to guarantee that if you allocate a chunk
+  which is smaller than or equal to 64 kilobytes, the extent of the
+  buffer you receive will not cross a 64K boundary.
+
+Just use appropriate new constants and get rid of
+the alignment code.
+
+Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h |    2 
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c  |   77 +++++++++-------------
+ 2 files changed, 33 insertions(+), 46 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+@@ -219,9 +219,7 @@ struct iwl_trans_pcie {
+       /* INT ICT Table */
+       __le32 *ict_tbl;
+-      void *ict_tbl_vir;
+       dma_addr_t ict_tbl_dma;
+-      dma_addr_t aligned_ict_tbl_dma;
+       int ict_index;
+       u32 inta;
+       bool use_ict;
+--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+@@ -1136,7 +1136,11 @@ void iwl_irq_tasklet(struct iwl_trans *t
+  * ICT functions
+  *
+  ******************************************************************************/
+-#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
++
++/* a device (PCI-E) page is 4096 bytes long */
++#define ICT_SHIFT     12
++#define ICT_SIZE      (1 << ICT_SHIFT)
++#define ICT_COUNT     (ICT_SIZE / sizeof(u32))
+ /* Free dram table */
+ void iwl_free_isr_ict(struct iwl_trans *trans)
+@@ -1144,21 +1148,19 @@ void iwl_free_isr_ict(struct iwl_trans *
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+-      if (trans_pcie->ict_tbl_vir) {
+-              dma_free_coherent(bus(trans)->dev,
+-                                (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
+-                                trans_pcie->ict_tbl_vir,
++      if (trans_pcie->ict_tbl) {
++              dma_free_coherent(bus(trans)->dev, ICT_SIZE,
++                                trans_pcie->ict_tbl,
+                                 trans_pcie->ict_tbl_dma);
+-              trans_pcie->ict_tbl_vir = NULL;
+-              memset(&trans_pcie->ict_tbl_dma, 0,
+-                      sizeof(trans_pcie->ict_tbl_dma));
+-              memset(&trans_pcie->aligned_ict_tbl_dma, 0,
+-                      sizeof(trans_pcie->aligned_ict_tbl_dma));
++              trans_pcie->ict_tbl = NULL;
++              trans_pcie->ict_tbl_dma = 0;
+       }
+ }
+-/* allocate dram shared table it is a PAGE_SIZE aligned
++/*
++ * allocate dram shared table, it is an aligned memory
++ * block of ICT_SIZE.
+  * also reset all data related to ICT table interrupt.
+  */
+ int iwl_alloc_isr_ict(struct iwl_trans *trans)
+@@ -1166,36 +1168,26 @@ int iwl_alloc_isr_ict(struct iwl_trans *
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+-      /* allocate shrared data table */
+-      trans_pcie->ict_tbl_vir =
+-              dma_alloc_coherent(bus(trans)->dev,
+-                                 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
+-                                 &trans_pcie->ict_tbl_dma, GFP_KERNEL);
+-      if (!trans_pcie->ict_tbl_vir)
++      trans_pcie->ict_tbl =
++              dma_alloc_coherent(bus(trans)->dev, ICT_SIZE,
++                                 &trans_pcie->ict_tbl_dma,
++                                 GFP_KERNEL);
++      if (!trans_pcie->ict_tbl)
+               return -ENOMEM;
+-      /* align table to PAGE_SIZE boundary */
+-      trans_pcie->aligned_ict_tbl_dma =
+-              ALIGN(trans_pcie->ict_tbl_dma, PAGE_SIZE);
+-
+-      IWL_DEBUG_ISR(trans, "ict dma addr %Lx dma aligned %Lx diff %d\n",
+-                         (unsigned long long)trans_pcie->ict_tbl_dma,
+-                         (unsigned long long)trans_pcie->aligned_ict_tbl_dma,
+-                         (int)(trans_pcie->aligned_ict_tbl_dma -
+-                         trans_pcie->ict_tbl_dma));
+-
+-      trans_pcie->ict_tbl =  trans_pcie->ict_tbl_vir +
+-                        (trans_pcie->aligned_ict_tbl_dma -
+-                        trans_pcie->ict_tbl_dma);
+-
+-      IWL_DEBUG_ISR(trans, "ict vir addr %p vir aligned %p diff %d\n",
+-                           trans_pcie->ict_tbl, trans_pcie->ict_tbl_vir,
+-                      (int)(trans_pcie->aligned_ict_tbl_dma -
+-                          trans_pcie->ict_tbl_dma));
++      /* just an API sanity check ... it is guaranteed to be aligned */
++      if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) {
++              iwl_free_isr_ict(trans);
++              return -EINVAL;
++      }
++
++      IWL_DEBUG_ISR(trans, "ict dma addr %Lx\n",
++                    (unsigned long long)trans_pcie->ict_tbl_dma);
++
++      IWL_DEBUG_ISR(trans, "ict vir addr %p\n", trans_pcie->ict_tbl);
+       /* reset table and index to all 0 */
+-      memset(trans_pcie->ict_tbl_vir, 0,
+-              (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
++      memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
+       trans_pcie->ict_index = 0;
+       /* add periodic RX interrupt */
+@@ -1213,23 +1205,20 @@ int iwl_reset_ict(struct iwl_trans *tran
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+-      if (!trans_pcie->ict_tbl_vir)
++      if (!trans_pcie->ict_tbl)
+               return 0;
+       spin_lock_irqsave(&trans->shrd->lock, flags);
+       iwl_disable_interrupts(trans);
+-      memset(&trans_pcie->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
++      memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
+-      val = trans_pcie->aligned_ict_tbl_dma >> PAGE_SHIFT;
++      val = trans_pcie->ict_tbl_dma >> ICT_SHIFT;
+       val |= CSR_DRAM_INT_TBL_ENABLE;
+       val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
+-      IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%X "
+-                      "aligned dma address %Lx\n",
+-                      val,
+-                      (unsigned long long)trans_pcie->aligned_ict_tbl_dma);
++      IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val);
+       iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val);
+       trans_pcie->use_ict = true;
diff --git a/queue-3.2/iwlagn-fix-tid-use-bug.patch b/queue-3.2/iwlagn-fix-tid-use-bug.patch
new file mode 100644 (file)
index 0000000..22102af
--- /dev/null
@@ -0,0 +1,48 @@
+From 9a215e40d70ae63762963ab3ccc7f31dd966dc6a Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Fri, 2 Dec 2011 12:22:54 -0800
+Subject: iwlagn: fix TID use bug
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 9a215e40d70ae63762963ab3ccc7f31dd966dc6a upstream.
+
+The driver everywhere uses max TID count as 9,
+which is wrong, it should be 8.
+
+I think the reason it uses 9 here is off-by-one
+confusion by whoever wrote this. We do use the
+value IWL_MAX_TID_COUNT for "not QoS/no TID"
+but that is completely correct even if it is 8
+and not 9 since 0-7 are only valid.
+
+As a side effect, this fixes the following bug:
+
+ Open BA session requested for 00:23:cd:16:8a:7e tid 8
+ ------------[ cut here ]------------
+ kernel BUG at drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h:350!
+ ...
+
+when you do
+echo "tx start 8" > /sys/kernel/debug/ieee80211/*/*/*/*/agg_status
+
+Reported-by: Nikolay Martynov <mar.kolya@gmail.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-commands.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
++++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
+@@ -809,7 +809,7 @@ struct iwl_qosparam_cmd {
+ #define       IWLAGN_STATION_COUNT    16
+ #define       IWL_INVALID_STATION     255
+-#define IWL_MAX_TID_COUNT     9
++#define IWL_MAX_TID_COUNT     8
+ #define STA_FLG_TX_RATE_MSK           cpu_to_le32(1 << 2)
+ #define STA_FLG_PWR_SAVE_MSK          cpu_to_le32(1 << 8)
diff --git a/queue-3.2/ore-fix-breakage-when-misc_filesystems-is-not-set.patch b/queue-3.2/ore-fix-breakage-when-misc_filesystems-is-not-set.patch
new file mode 100644 (file)
index 0000000..39a504b
--- /dev/null
@@ -0,0 +1,81 @@
+From 831c2dc5f47c1dc79c32229d75065ada1dcc66e1 Mon Sep 17 00:00:00 2001
+From: Boaz Harrosh <bharrosh@panasas.com>
+Date: Tue, 29 Nov 2011 15:35:53 -0800
+Subject: ore: FIX breakage when MISC_FILESYSTEMS is not set
+
+From: Boaz Harrosh <bharrosh@panasas.com>
+
+commit 831c2dc5f47c1dc79c32229d75065ada1dcc66e1 upstream.
+
+As Reported by Randy Dunlap
+
+When MISC_FILESYSTEMS is not enabled and NFS4.1 is:
+
+fs/built-in.o: In function `objio_alloc_io_state':
+objio_osd.c:(.text+0xcb525): undefined reference to `ore_get_rw_state'
+fs/built-in.o: In function `_write_done':
+objio_osd.c:(.text+0xcb58d): undefined reference to `ore_check_io'
+fs/built-in.o: In function `_read_done':
+...
+
+When MISC_FILESYSTEMS, which is more of a GUI thing then anything else,
+is not selected. exofs/Kconfig is never examined during Kconfig,
+and it can not do it's magic stuff to automatically select everything
+needed.
+
+We must split exofs/Kconfig in two. The ore one is always included.
+And the exofs one is left in it's old place in the menu.
+
+Reported-by: Randy Dunlap <rdunlap@xenotime.net>
+Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/Kconfig           |    2 ++
+ fs/exofs/Kconfig     |   11 -----------
+ fs/exofs/Kconfig.ore |   12 ++++++++++++
+ 3 files changed, 14 insertions(+), 11 deletions(-)
+
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -218,6 +218,8 @@ source "fs/exofs/Kconfig"
+ endif # MISC_FILESYSTEMS
++source "fs/exofs/Kconfig.ore"
++
+ menuconfig NETWORK_FILESYSTEMS
+       bool "Network File Systems"
+       default y
+--- a/fs/exofs/Kconfig
++++ b/fs/exofs/Kconfig
+@@ -1,14 +1,3 @@
+-# Note ORE needs to "select ASYNC_XOR". So Not to force multiple selects
+-# for every ORE user we do it like this. Any user should add itself here
+-# at the "depends on EXOFS_FS || ..." with an ||. The dependencies are
+-# selected here, and we default to "ON". So in effect it is like been
+-# selected by any of the users.
+-config ORE
+-      tristate
+-      depends on EXOFS_FS || PNFS_OBJLAYOUT
+-      select ASYNC_XOR
+-      default SCSI_OSD_ULD
+-
+ config EXOFS_FS
+       tristate "exofs: OSD based file system support"
+       depends on SCSI_OSD_ULD
+--- /dev/null
++++ b/fs/exofs/Kconfig.ore
+@@ -0,0 +1,12 @@
++# ORE - Objects Raid Engine (libore.ko)
++#
++# Note ORE needs to "select ASYNC_XOR". So Not to force multiple selects
++# for every ORE user we do it like this. Any user should add itself here
++# at the "depends on EXOFS_FS || ..." with an ||. The dependencies are
++# selected here, and we default to "ON". So in effect it is like been
++# selected by any of the users.
++config ORE
++      tristate
++      depends on EXOFS_FS || PNFS_OBJLAYOUT
++      select ASYNC_XOR
++      default SCSI_OSD_ULD
diff --git a/queue-3.2/ore-fix-bug_on-too-few-sgs-when-reading.patch b/queue-3.2/ore-fix-bug_on-too-few-sgs-when-reading.patch
new file mode 100644 (file)
index 0000000..1f63f9e
--- /dev/null
@@ -0,0 +1,52 @@
+From 361aba569f55dd159b850489a3538253afbb3973 Mon Sep 17 00:00:00 2001
+From: Boaz Harrosh <bharrosh@panasas.com>
+Date: Wed, 28 Dec 2011 19:14:23 +0200
+Subject: ore: fix BUG_ON, too few sgs when reading
+
+From: Boaz Harrosh <bharrosh@panasas.com>
+
+commit 361aba569f55dd159b850489a3538253afbb3973 upstream.
+
+When reading RAID5 files, in rare cases, we calculated too
+few sg segments. There should be two extra for the beginning
+and end partial units.
+
+Also "too few sg segments" should not be a BUG_ON there is
+all the mechanics in place to handle it, as a short read.
+So just return -ENOMEM and the rest of the code will gracefully
+split the IO.
+
+Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/exofs/ore.c      |    2 +-
+ fs/exofs/ore_raid.c |    6 +++++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/exofs/ore.c
++++ b/fs/exofs/ore.c
+@@ -266,7 +266,7 @@ int  ore_get_rw_state(struct ore_layout
+                       /* first/last seg is split */
+                       num_raid_units += layout->group_width;
+-                      sgs_per_dev = div_u64(num_raid_units, data_devs);
++                      sgs_per_dev = div_u64(num_raid_units, data_devs) + 2;
+               } else {
+                       /* For Writes add parity pages array. */
+                       max_par_pages = num_raid_units * pages_in_unit *
+--- a/fs/exofs/ore_raid.c
++++ b/fs/exofs/ore_raid.c
+@@ -551,7 +551,11 @@ int _ore_add_parity_unit(struct ore_io_s
+                           unsigned cur_len)
+ {
+       if (ios->reading) {
+-              BUG_ON(per_dev->cur_sg >= ios->sgs_per_dev);
++              if (per_dev->cur_sg >= ios->sgs_per_dev) {
++                      ORE_DBGMSG("cur_sg(%d) >= sgs_per_dev(%d)\n" ,
++                              per_dev->cur_sg, ios->sgs_per_dev);
++                      return -ENOMEM;
++              }
+               _ore_add_sg_seg(per_dev, cur_len, true);
+       } else {
+               struct __stripe_pages_2d *sp2d = ios->sp2d;
diff --git a/queue-3.2/ore-fix-crash-in-case-of-an-io-error.patch b/queue-3.2/ore-fix-crash-in-case-of-an-io-error.patch
new file mode 100644 (file)
index 0000000..335e479
--- /dev/null
@@ -0,0 +1,39 @@
+From ffefb8eaa367e8a5c14f779233d9da1fbc23d164 Mon Sep 17 00:00:00 2001
+From: Boaz Harrosh <bharrosh@panasas.com>
+Date: Tue, 27 Dec 2011 19:23:36 +0200
+Subject: ore: Fix crash in case of an IO error.
+
+From: Boaz Harrosh <bharrosh@panasas.com>
+
+commit ffefb8eaa367e8a5c14f779233d9da1fbc23d164 upstream.
+
+The users of ore_check_io() expect the reported device
+(In case of error) to be indexed relative to the passed-in
+ore_components table, and not the logical dev index.
+
+This causes a crash inside objlayoutdriver in case of
+an IO error.
+
+Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/exofs/ore.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/exofs/ore.c
++++ b/fs/exofs/ore.c
+@@ -445,10 +445,10 @@ int ore_check_io(struct ore_io_state *io
+                       u64 residual = ios->reading ?
+                                       or->in.residual : or->out.residual;
+                       u64 offset = (ios->offset + ios->length) - residual;
+-                      struct ore_dev *od = ios->oc->ods[
+-                                      per_dev->dev - ios->oc->first_dev];
++                      unsigned dev = per_dev->dev - ios->oc->first_dev;
++                      struct ore_dev *od = ios->oc->ods[dev];
+-                      on_dev_error(ios, od, per_dev->dev, osi.osd_err_pri,
++                      on_dev_error(ios, od, dev, osi.osd_err_pri,
+                                    offset, residual);
+               }
+               if (osi.osd_err_pri >= acumulated_osd_err) {
diff --git a/queue-3.2/ore-must-support-none-page-aligned-io.patch b/queue-3.2/ore-must-support-none-page-aligned-io.patch
new file mode 100644 (file)
index 0000000..c2c3cb1
--- /dev/null
@@ -0,0 +1,161 @@
+From 724577ca355795b0a25c93ccbeee927871ca1a77 Mon Sep 17 00:00:00 2001
+From: Boaz Harrosh <bharrosh@panasas.com>
+Date: Wed, 28 Dec 2011 19:21:45 +0200
+Subject: ore: Must support none-PAGE-aligned IO
+
+From: Boaz Harrosh <bharrosh@panasas.com>
+
+commit 724577ca355795b0a25c93ccbeee927871ca1a77 upstream.
+
+NFS might send us offsets that are not PAGE aligned. So
+we must read in the reminder of the first/last pages, in cases
+we need it for Parity calculations.
+
+We only add an sg segments to read the partial page. But
+we don't mark it as read=true because it is a lock-for-write
+page.
+
+TODO: In some cases (IO spans a single unit) we can just
+adjust the raid_unit offset/length, but this is left for
+later Kernels.
+
+Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/exofs/ore_raid.c |   72 +++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 60 insertions(+), 12 deletions(-)
+
+--- a/fs/exofs/ore_raid.c
++++ b/fs/exofs/ore_raid.c
+@@ -328,8 +328,8 @@ static int _alloc_read_4_write(struct or
+ /* @si contains info of the to-be-inserted page. Update of @si should be
+  * maintained by caller. Specificaly si->dev, si->obj_offset, ...
+  */
+-static int _add_to_read_4_write(struct ore_io_state *ios,
+-                              struct ore_striping_info *si, struct page *page)
++static int _add_to_r4w(struct ore_io_state *ios, struct ore_striping_info *si,
++                     struct page *page, unsigned pg_len)
+ {
+       struct request_queue *q;
+       struct ore_per_dev_state *per_dev;
+@@ -366,17 +366,60 @@ static int _add_to_read_4_write(struct o
+               _ore_add_sg_seg(per_dev, gap, true);
+       }
+       q = osd_request_queue(ore_comp_dev(read_ios->oc, per_dev->dev));
+-      added_len = bio_add_pc_page(q, per_dev->bio, page, PAGE_SIZE, 0);
+-      if (unlikely(added_len != PAGE_SIZE)) {
++      added_len = bio_add_pc_page(q, per_dev->bio, page, pg_len,
++                                  si->obj_offset % PAGE_SIZE);
++      if (unlikely(added_len != pg_len)) {
+               ORE_DBGMSG("Failed to bio_add_pc_page bi_vcnt=%d\n",
+                             per_dev->bio->bi_vcnt);
+               return -ENOMEM;
+       }
+-      per_dev->length += PAGE_SIZE;
++      per_dev->length += pg_len;
+       return 0;
+ }
++/* read the beginning of an unaligned first page */
++static int _add_to_r4w_first_page(struct ore_io_state *ios, struct page *page)
++{
++      struct ore_striping_info si;
++      unsigned pg_len;
++
++      ore_calc_stripe_info(ios->layout, ios->offset, 0, &si);
++
++      pg_len = si.obj_offset % PAGE_SIZE;
++      si.obj_offset -= pg_len;
++
++      ORE_DBGMSG("offset=0x%llx len=0x%x index=0x%lx dev=%x\n",
++                 _LLU(si.obj_offset), pg_len, page->index, si.dev);
++
++      return _add_to_r4w(ios, &si, page, pg_len);
++}
++
++/* read the end of an incomplete last page */
++static int _add_to_r4w_last_page(struct ore_io_state *ios, u64 *offset)
++{
++      struct ore_striping_info si;
++      struct page *page;
++      unsigned pg_len, p, c;
++
++      ore_calc_stripe_info(ios->layout, *offset, 0, &si);
++
++      p = si.unit_off / PAGE_SIZE;
++      c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1,
++                     ios->layout->mirrors_p1, si.par_dev, si.dev);
++      page = ios->sp2d->_1p_stripes[p].pages[c];
++
++      pg_len = PAGE_SIZE - (si.unit_off % PAGE_SIZE);
++      *offset += pg_len;
++
++      ORE_DBGMSG("p=%d, c=%d next-offset=0x%llx len=0x%x dev=%x par_dev=%d\n",
++                 p, c, _LLU(*offset), pg_len, si.dev, si.par_dev);
++
++      BUG_ON(!page);
++
++      return _add_to_r4w(ios, &si, page, pg_len);
++}
++
+ static void _mark_read4write_pages_uptodate(struct ore_io_state *ios, int ret)
+ {
+       struct bio_vec *bv;
+@@ -444,9 +487,13 @@ static int _read_4_write(struct ore_io_s
+                       struct page **pp = &_1ps->pages[c];
+                       bool uptodate;
+-                      if (*pp)
++                      if (*pp) {
++                              if (ios->offset % PAGE_SIZE)
++                                      /* Read the remainder of the page */
++                                      _add_to_r4w_first_page(ios, *pp);
+                               /* to-be-written pages start here */
+                               goto read_last_stripe;
++                      }
+                       *pp = ios->r4w->get_page(ios->private, offset,
+                                                &uptodate);
+@@ -454,7 +501,7 @@ static int _read_4_write(struct ore_io_s
+                               return -ENOMEM;
+                       if (!uptodate)
+-                              _add_to_read_4_write(ios, &read_si, *pp);
++                              _add_to_r4w(ios, &read_si, *pp, PAGE_SIZE);
+                       /* Mark read-pages to be cache_released */
+                       _1ps->page_is_read[c] = true;
+@@ -465,8 +512,11 @@ static int _read_4_write(struct ore_io_s
+       }
+ read_last_stripe:
+-      offset = ios->offset + (ios->length + PAGE_SIZE - 1) /
+-                              PAGE_SIZE * PAGE_SIZE;
++      offset = ios->offset + ios->length;
++      if (offset % PAGE_SIZE)
++              _add_to_r4w_last_page(ios, &offset);
++              /* offset will be aligned to next page */
++
+       last_stripe_end = div_u64(offset + bytes_in_stripe - 1, bytes_in_stripe)
+                                * bytes_in_stripe;
+       if (offset == last_stripe_end) /* Optimize for the aligned case */
+@@ -503,7 +553,7 @@ read_last_stripe:
+                       /* Mark read-pages to be cache_released */
+                       _1ps->page_is_read[c] = true;
+                       if (!uptodate)
+-                              _add_to_read_4_write(ios, &read_si, page);
++                              _add_to_r4w(ios, &read_si, page, PAGE_SIZE);
+               }
+               offset += PAGE_SIZE;
+@@ -616,8 +666,6 @@ int _ore_post_alloc_raid_stuff(struct or
+                       return -ENOMEM;
+               }
+-              BUG_ON(ios->offset % PAGE_SIZE);
+-
+               /* Round io down to last full strip */
+               first_stripe = div_u64(ios->offset, stripe_size);
+               last_stripe = div_u64(ios->offset + ios->length, stripe_size);
diff --git a/queue-3.2/perf-fix-parsing-of-__print_flags-in-tp_printk.patch b/queue-3.2/perf-fix-parsing-of-__print_flags-in-tp_printk.patch
new file mode 100644 (file)
index 0000000..50a71b8
--- /dev/null
@@ -0,0 +1,35 @@
+From 49908a1b25d448d68fd26faca260e1850201575f Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Fri, 4 Nov 2011 16:32:25 -0400
+Subject: perf: Fix parsing of __print_flags() in TP_printk()
+
+From: Steven Rostedt <srostedt@redhat.com>
+
+commit 49908a1b25d448d68fd26faca260e1850201575f upstream.
+
+A update is made to the sched:sched_switch event that adds some
+logic to the first parameter of the __print_flags() that shows the
+state of tasks. This change cause perf to fail parsing the flags.
+
+A simple fix is needed to have the parser be able to process ops
+within the argument.
+
+Reported-by: Andrew Vagin <avagin@openvz.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ tools/perf/util/trace-event-parse.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/tools/perf/util/trace-event-parse.c
++++ b/tools/perf/util/trace-event-parse.c
+@@ -1582,6 +1582,8 @@ process_symbols(struct event *event, str
+       field = malloc_or_die(sizeof(*field));
+       type = process_arg(event, field, &token);
++      while (type == EVENT_OP)
++              type = process_op(event, field, &token);
+       if (test_type_token(type, token, EVENT_DELIM, ","))
+               goto out_free;
diff --git a/queue-3.2/reiserfs-fix-quota-mount-option-parsing.patch b/queue-3.2/reiserfs-fix-quota-mount-option-parsing.patch
new file mode 100644 (file)
index 0000000..bdae507
--- /dev/null
@@ -0,0 +1,32 @@
+From a06d789b424190e9f59da391681f908486db2554 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 21 Dec 2011 17:35:34 +0100
+Subject: reiserfs: Fix quota mount option parsing
+
+From: Jan Kara <jack@suse.cz>
+
+commit a06d789b424190e9f59da391681f908486db2554 upstream.
+
+When jqfmt mount option is not specified on remount, we mistakenly clear
+s_jquota_fmt value stored in superblock. Fix the problem.
+
+CC: reiserfs-devel@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/reiserfs/super.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -1164,7 +1164,8 @@ static void handle_quota_files(struct su
+                       kfree(REISERFS_SB(s)->s_qf_names[i]);
+               REISERFS_SB(s)->s_qf_names[i] = qf_names[i];
+       }
+-      REISERFS_SB(s)->s_jquota_fmt = *qfmt;
++      if (*qfmt)
++              REISERFS_SB(s)->s_jquota_fmt = *qfmt;
+ }
+ #endif
diff --git a/queue-3.2/reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch b/queue-3.2/reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch
new file mode 100644 (file)
index 0000000..dea6af2
--- /dev/null
@@ -0,0 +1,67 @@
+From a9e36da655e54545c3289b2a0700b5c443de0edd Mon Sep 17 00:00:00 2001
+From: Jeff Mahoney <jeffm@suse.com>
+Date: Wed, 21 Dec 2011 21:18:43 +0100
+Subject: reiserfs: Force inode evictions before umount to avoid crash
+
+From: Jeff Mahoney <jeffm@suse.com>
+
+commit a9e36da655e54545c3289b2a0700b5c443de0edd upstream.
+
+This patch fixes a crash in reiserfs_delete_xattrs during umount.
+
+When shrink_dcache_for_umount clears the dcache from
+generic_shutdown_super, delayed evictions are forced to disk. If an
+evicted inode has extended attributes associated with it, it will
+need to walk the xattr tree to locate and remove them.
+
+But since shrink_dcache_for_umount will BUG if it encounters active
+dentries, the xattr tree must be released before it's called or it will
+crash during every umount.
+
+This patch forces the evictions to occur before generic_shutdown_super
+by calling shrink_dcache_sb first. The additional evictions caused
+by the removal of each associated xattr file and dir will be automatically
+handled as they're added to the LRU list.
+
+CC: reiserfs-devel@vger.kernel.org
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/reiserfs/super.c |   24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -453,16 +453,20 @@ int remove_save_link(struct inode *inode
+ static void reiserfs_kill_sb(struct super_block *s)
+ {
+       if (REISERFS_SB(s)) {
+-              if (REISERFS_SB(s)->xattr_root) {
+-                      d_invalidate(REISERFS_SB(s)->xattr_root);
+-                      dput(REISERFS_SB(s)->xattr_root);
+-                      REISERFS_SB(s)->xattr_root = NULL;
+-              }
+-              if (REISERFS_SB(s)->priv_root) {
+-                      d_invalidate(REISERFS_SB(s)->priv_root);
+-                      dput(REISERFS_SB(s)->priv_root);
+-                      REISERFS_SB(s)->priv_root = NULL;
+-              }
++              /*
++               * Force any pending inode evictions to occur now. Any
++               * inodes to be removed that have extended attributes
++               * associated with them need to clean them up before
++               * we can release the extended attribute root dentries.
++               * shrink_dcache_for_umount will BUG if we don't release
++               * those before it's called so ->put_super is too late.
++               */
++              shrink_dcache_sb(s);
++
++              dput(REISERFS_SB(s)->xattr_root);
++              REISERFS_SB(s)->xattr_root = NULL;
++              dput(REISERFS_SB(s)->priv_root);
++              REISERFS_SB(s)->priv_root = NULL;
+       }
+       kill_block_super(s);
index 2d38c4fbe2adf913e112134cd129a4fb0e14433e..6b29595230ef8e70df383bd120917f4dcfbcc0ba 100644 (file)
@@ -11,3 +11,24 @@ wl12xx-check-buffer-bound-when-processing-nvs-data.patch
 wl12xx-restore-testmode-abi.patch
 powerpc-time-handle-wrapping-of-decrementer.patch
 powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch
+ib-qib-fix-a-possible-data-corruption-when-receiving.patch
+ib-uverbs-protect-qp-multicast-list.patch
+iwlagn-fix-tid-use-bug.patch
+iwlagn-fix-remove-use-of-page_size.patch
+perf-fix-parsing-of-__print_flags-in-tp_printk.patch
+ore-fix-crash-in-case-of-an-io-error.patch
+ore-fix-bug_on-too-few-sgs-when-reading.patch
+ore-must-support-none-page-aligned-io.patch
+ore-fix-breakage-when-misc_filesystems-is-not-set.patch
+reiserfs-fix-quota-mount-option-parsing.patch
+reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch
+ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch
+drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch
+drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch
+usb-update-documentation-for-usbmon.patch
+usbfs-fix-oops-related-to-user-namespace-conversion.patch
+atmel_serial-fix-spinlock-lockup-in-rs485-code.patch
+cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch
+udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch
+drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch
+usb-isight-fix-kernel-bug-when-loading-firmware.patch
diff --git a/queue-3.2/udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch b/queue-3.2/udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch
new file mode 100644 (file)
index 0000000..2daecda
--- /dev/null
@@ -0,0 +1,125 @@
+From d2eb8c359309ec45d6bf5b147303ab8e13be86ea Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Sat, 10 Dec 2011 02:30:48 +0100
+Subject: udf: Fix deadlock when converting file from in-ICB one to normal one
+
+From: Jan Kara <jack@suse.cz>
+
+commit d2eb8c359309ec45d6bf5b147303ab8e13be86ea upstream.
+
+During BKL removal in 2.6.38, conversion of files from in-ICB format to normal
+format got broken. We call ->writepage with i_data_sem held but udf_get_block()
+also acquires i_data_sem thus creating A-A deadlock.
+
+We fix the problem by dropping i_data_sem before calling ->writepage() which is
+safe since i_mutex still protects us against any changes in the file. Also fix
+pagelock - i_data_sem lock inversion in udf_expand_file_adinicb() by dropping
+i_data_sem before calling find_or_create_page().
+
+Reported-by: Matthias Matiak <netzpython@mail-on.us>
+Tested-by: Matthias Matiak <netzpython@mail-on.us>
+Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/udf/file.c  |    6 +++---
+ fs/udf/inode.c |   21 ++++++++++++++++++---
+ 2 files changed, 21 insertions(+), 6 deletions(-)
+
+--- a/fs/udf/file.c
++++ b/fs/udf/file.c
+@@ -125,7 +125,6 @@ static ssize_t udf_file_aio_write(struct
+                       err = udf_expand_file_adinicb(inode);
+                       if (err) {
+                               udf_debug("udf_expand_adinicb: err=%d\n", err);
+-                              up_write(&iinfo->i_data_sem);
+                               return err;
+                       }
+               } else {
+@@ -133,9 +132,10 @@ static ssize_t udf_file_aio_write(struct
+                               iinfo->i_lenAlloc = pos + count;
+                       else
+                               iinfo->i_lenAlloc = inode->i_size;
++                      up_write(&iinfo->i_data_sem);
+               }
+-      }
+-      up_write(&iinfo->i_data_sem);
++      } else
++              up_write(&iinfo->i_data_sem);
+       retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
+       if (retval > 0)
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -151,6 +151,12 @@ const struct address_space_operations ud
+       .bmap           = udf_bmap,
+ };
++/*
++ * Expand file stored in ICB to a normal one-block-file
++ *
++ * This function requires i_data_sem for writing and releases it.
++ * This function requires i_mutex held
++ */
+ int udf_expand_file_adinicb(struct inode *inode)
+ {
+       struct page *page;
+@@ -169,9 +175,15 @@ int udf_expand_file_adinicb(struct inode
+                       iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
+               /* from now on we have normal address_space methods */
+               inode->i_data.a_ops = &udf_aops;
++              up_write(&iinfo->i_data_sem);
+               mark_inode_dirty(inode);
+               return 0;
+       }
++      /*
++       * Release i_data_sem so that we can lock a page - page lock ranks
++       * above i_data_sem. i_mutex still protects us against file changes.
++       */
++      up_write(&iinfo->i_data_sem);
+       page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS);
+       if (!page)
+@@ -187,6 +199,7 @@ int udf_expand_file_adinicb(struct inode
+               SetPageUptodate(page);
+               kunmap(page);
+       }
++      down_write(&iinfo->i_data_sem);
+       memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00,
+              iinfo->i_lenAlloc);
+       iinfo->i_lenAlloc = 0;
+@@ -196,17 +209,20 @@ int udf_expand_file_adinicb(struct inode
+               iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
+       /* from now on we have normal address_space methods */
+       inode->i_data.a_ops = &udf_aops;
++      up_write(&iinfo->i_data_sem);
+       err = inode->i_data.a_ops->writepage(page, &udf_wbc);
+       if (err) {
+               /* Restore everything back so that we don't lose data... */
+               lock_page(page);
+               kaddr = kmap(page);
++              down_write(&iinfo->i_data_sem);
+               memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr,
+                      inode->i_size);
+               kunmap(page);
+               unlock_page(page);
+               iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
+               inode->i_data.a_ops = &udf_adinicb_aops;
++              up_write(&iinfo->i_data_sem);
+       }
+       page_cache_release(page);
+       mark_inode_dirty(inode);
+@@ -1111,10 +1127,9 @@ int udf_setsize(struct inode *inode, lof
+                       if (bsize <
+                           (udf_file_entry_alloc_offset(inode) + newsize)) {
+                               err = udf_expand_file_adinicb(inode);
+-                              if (err) {
+-                                      up_write(&iinfo->i_data_sem);
++                              if (err)
+                                       return err;
+-                              }
++                              down_write(&iinfo->i_data_sem);
+                       } else
+                               iinfo->i_lenAlloc = newsize;
+               }
diff --git a/queue-3.2/usb-isight-fix-kernel-bug-when-loading-firmware.patch b/queue-3.2/usb-isight-fix-kernel-bug-when-loading-firmware.patch
new file mode 100644 (file)
index 0000000..57ad593
--- /dev/null
@@ -0,0 +1,45 @@
+From 59bf5cf94f0fa3b08fb1258b52649077b7d0914d Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Date: Mon, 5 Dec 2011 14:02:59 -0800
+Subject: USB: isight: fix kernel bug when loading firmware
+
+From: Greg Kroah-Hartman <gregkh@suse.de>
+
+commit 59bf5cf94f0fa3b08fb1258b52649077b7d0914d upstream.
+
+We were sending data on the stack when uploading firmware, which causes
+some machines fits, and is not allowed.  Fix this by using the buffer we
+already had around for this very purpose.
+
+Reported-by: Wouter M. Koolen <wmkoolen@cwi.nl>
+Tested-by: Wouter M. Koolen <wmkoolen@cwi.nl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/misc/isight_firmware.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/isight_firmware.c
++++ b/drivers/usb/misc/isight_firmware.c
+@@ -55,8 +55,9 @@ static int isight_firmware_load(struct u
+       ptr = firmware->data;
++      buf[0] = 0x01;
+       if (usb_control_msg
+-          (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1,
++          (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
+            300) != 1) {
+               printk(KERN_ERR
+                      "Failed to initialise isight firmware loader\n");
+@@ -100,8 +101,9 @@ static int isight_firmware_load(struct u
+               }
+       }
++      buf[0] = 0x00;
+       if (usb_control_msg
+-          (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
++          (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
+            300) != 1) {
+               printk(KERN_ERR "isight firmware loading completion failed\n");
+               ret = -ENODEV;
diff --git a/queue-3.2/usb-update-documentation-for-usbmon.patch b/queue-3.2/usb-update-documentation-for-usbmon.patch
new file mode 100644 (file)
index 0000000..d7cdebb
--- /dev/null
@@ -0,0 +1,52 @@
+From d8cae98cddd286e38db1724dda1b0e7b467f9237 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 4 Jan 2012 16:36:35 -0500
+Subject: USB: update documentation for usbmon
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit d8cae98cddd286e38db1724dda1b0e7b467f9237 upstream.
+
+The documentation for usbmon is out of date; the usbfs "devices" file
+now exists in /sys/kernel/debug/usb rather than /proc/bus/usb.  This
+patch (as1505) updates the documentation accordingly, and also
+mentions that the necessary information can be found by running lsusb.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Pete Zaitcev <zaitcev@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/usb/usbmon.txt |   14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/Documentation/usb/usbmon.txt
++++ b/Documentation/usb/usbmon.txt
+@@ -47,10 +47,11 @@ This allows to filter away annoying devi
+ 2. Find which bus connects to the desired device
+-Run "cat /proc/bus/usb/devices", and find the T-line which corresponds to
+-the device. Usually you do it by looking for the vendor string. If you have
+-many similar devices, unplug one and compare two /proc/bus/usb/devices outputs.
+-The T-line will have a bus number. Example:
++Run "cat /sys/kernel/debug/usb/devices", and find the T-line which corresponds
++to the device. Usually you do it by looking for the vendor string. If you have
++many similar devices, unplug one and compare the two
++/sys/kernel/debug/usb/devices outputs. The T-line will have a bus number.
++Example:
+ T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12  MxCh= 0
+ D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
+@@ -58,7 +59,10 @@ P:  Vendor=0557 ProdID=2004 Rev= 1.00
+ S:  Manufacturer=ATEN
+ S:  Product=UC100KM V2.00
+-Bus=03 means it's bus 3.
++"Bus=03" means it's bus 3. Alternatively, you can look at the output from
++"lsusb" and get the bus number from the appropriate line. Example:
++
++Bus 003 Device 002: ID 0557:2004 ATEN UC100KM V2.00
+ 3. Start 'cat'
diff --git a/queue-3.2/usbfs-fix-oops-related-to-user-namespace-conversion.patch b/queue-3.2/usbfs-fix-oops-related-to-user-namespace-conversion.patch
new file mode 100644 (file)
index 0000000..897b87c
--- /dev/null
@@ -0,0 +1,123 @@
+From 1b41c8321e495337e877ca02d0b9680bc4112eff Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Fri, 16 Dec 2011 11:26:30 -0800
+Subject: usbfs: Fix oops related to user namespace conversion.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 1b41c8321e495337e877ca02d0b9680bc4112eff upstream.
+
+When running the Point Grey "flycap" program for their USB 3.0 camera
+(which was running as a USB 2.0 device for some reason), I trigger this
+oops whenever I try to open a video stream:
+
+Dec 15 16:48:34 puck kernel: [ 1798.715559] BUG: unable to handle kernel NULL pointer dereference at           (null)
+Dec 15 16:48:34 puck kernel: [ 1798.719153] IP: [<ffffffff8147841e>] free_async+0x1e/0x70
+Dec 15 16:48:34 puck kernel: [ 1798.720991] PGD 6f833067 PUD 6fc56067 PMD 0
+Dec 15 16:48:34 puck kernel: [ 1798.722815] Oops: 0002 [#1] SMP
+Dec 15 16:48:34 puck kernel: [ 1798.724627] CPU 0
+Dec 15 16:48:34 puck kernel: [ 1798.724636] Modules linked in: ecryptfs encrypted_keys sha1_generic trusted binfmt_misc sha256_generic aesni_intel cryptd aes_x86_64 aes_generic parport_pc dm_crypt ppdev joydev snd_hda_codec_hdmi snd_hda_codec_conexant arc4 iwlwifi snd_hda_intel snd_hda_codec snd_hwdep snd_pcm thinkpad_acpi mac80211 snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer btusb uvcvideo snd_seq_device bluetooth videodev psmouse snd v4l2_compat_ioctl32 serio_raw tpm_tis cfg80211 tpm tpm_bios nvram soundcore snd_page_alloc lp parport i915 xhci_hcd ahci libahci drm_kms_helper drm sdhci_pci sdhci e1000e i2c_algo_bit video
+Dec 15 16:48:34 puck kernel: [ 1798.734212]
+Dec 15 16:48:34 puck kernel: [ 1798.736162] Pid: 2713, comm: FlyCap2 Not tainted 3.2.0-rc5+ #28 LENOVO 4286CTO/4286CTO
+Dec 15 16:48:34 puck kernel: [ 1798.738148] RIP: 0010:[<ffffffff8147841e>]  [<ffffffff8147841e>] free_async+0x1e/0x70
+Dec 15 16:48:34 puck kernel: [ 1798.740134] RSP: 0018:ffff88005715fd78  EFLAGS: 00010296
+Dec 15 16:48:34 puck kernel: [ 1798.742118] RAX: 00000000fffffff4 RBX: ffff88006fe8f900 RCX: 0000000000004118
+Dec 15 16:48:34 puck kernel: [ 1798.744116] RDX: 0000000001000000 RSI: 0000000000016390 RDI: 0000000000000000
+Dec 15 16:48:34 puck kernel: [ 1798.746087] RBP: ffff88005715fd88 R08: 0000000000000000 R09: ffffffff8146f22e
+Dec 15 16:48:34 puck kernel: [ 1798.748018] R10: ffff88006e520ac0 R11: 0000000000000001 R12: ffff88005715fe28
+Dec 15 16:48:34 puck kernel: [ 1798.749916] R13: ffff88005d31df00 R14: ffff88006fe8f900 R15: 00007f688c995cb8
+Dec 15 16:48:34 puck kernel: [ 1798.751785] FS:  00007f68a366da40(0000) GS:ffff880100200000(0000) knlGS:0000000000000000
+Dec 15 16:48:34 puck kernel: [ 1798.753659] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+Dec 15 16:48:34 puck kernel: [ 1798.755509] CR2: 0000000000000000 CR3: 00000000706bb000 CR4: 00000000000406f0
+Dec 15 16:48:34 puck kernel: [ 1798.757334] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+Dec 15 16:48:34 puck kernel: [ 1798.759124] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+Dec 15 16:48:34 puck kernel: [ 1798.760871] Process FlyCap2 (pid: 2713, threadinfo ffff88005715e000, task ffff88006c675b80)
+Dec 15 16:48:34 puck kernel: [ 1798.762605] Stack:
+Dec 15 16:48:34 puck kernel: [ 1798.764297]  ffff88005715fe28 0000000000000000 ffff88005715fe08 ffffffff81479058
+Dec 15 16:48:34 puck kernel: [ 1798.766020]  0000000000000000 ffffea0000004000 ffff880000004118 0000000000000000
+Dec 15 16:48:34 puck kernel: [ 1798.767750]  ffff880000000001 ffff88006e520ac0 fffffff46fd81180 0000000000000000
+Dec 15 16:48:34 puck kernel: [ 1798.769472] Call Trace:
+Dec 15 16:48:34 puck kernel: [ 1798.771147]  [<ffffffff81479058>] proc_do_submiturb+0x778/0xa00
+Dec 15 16:48:34 puck kernel: [ 1798.772798]  [<ffffffff8147a5fd>] usbdev_do_ioctl+0x24d/0x1200
+Dec 15 16:48:34 puck kernel: [ 1798.774410]  [<ffffffff8147b5de>] usbdev_ioctl+0xe/0x20
+Dec 15 16:48:34 puck kernel: [ 1798.775975]  [<ffffffff81189259>] do_vfs_ioctl+0x99/0x600
+Dec 15 16:48:34 puck kernel: [ 1798.777534]  [<ffffffff81189851>] sys_ioctl+0x91/0xa0
+Dec 15 16:48:34 puck kernel: [ 1798.779088]  [<ffffffff816247c2>] system_call_fastpath+0x16/0x1b
+ec 15 16:48:34 puck kernel: [ 1798.780634] Code: 51 ff ff ff e9 29 ff ff ff 0f 1f 40 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 89 fb 48 8b 7f 18 e8 a6 ea c0 ff 4
+8 8b 7b 20 <f0> ff 0f 0f 94 c0 84 c0 74 05 e8 d3 99 c1 ff 48 8b 43 40 48 8b
+Dec 15 16:48:34 puck kernel: [ 1798.783970] RIP  [<ffffffff8147841e>] free_async+0x1e/0x70
+Dec 15 16:48:34 puck kernel: [ 1798.785630]  RSP <ffff88005715fd78>
+Dec 15 16:48:34 puck kernel: [ 1798.787274] CR2: 0000000000000000
+Dec 15 16:48:34 puck kernel: [ 1798.794728] ---[ end trace 52894d3355f88d19 ]---
+
+markup_oops.pl says the oops is in put_cred:
+
+ ffffffff81478401:      48 89 e5                mov    %rsp,%rbp
+ ffffffff81478404:      53                      push   %rbx
+ ffffffff81478405:      48 83 ec 08             sub    $0x8,%rsp
+ ffffffff81478409:      e8 f2 c0 1a 00          callq  ffffffff81624500 <mcount>
+ ffffffff8147840e:      48 89 fb                mov    %rdi,%rbx   |  %ebx => ffff88006fe8f900
+        put_pid(as->pid);
+ ffffffff81478411:      48 8b 7f 18             mov    0x18(%rdi),%rdi
+ ffffffff81478415:      e8 a6 ea c0 ff          callq  ffffffff81086ec0 <put_pid>
+        put_cred(as->cred);
+ ffffffff8147841a:      48 8b 7b 20             mov    0x20(%rbx),%rdi |  %edi => 0  %ebx = ffff88006fe8f900
+  */
+ static inline int atomic_dec_and_test(atomic_t *v)
+ {
+        unsigned char c;
+
+        asm volatile(LOCK_PREFIX "decl %0; sete %1"
+*ffffffff8147841e:      f0 ff 0f                lock decl (%rdi)   |  %edi = 0 <--- faulting instruction
+ ffffffff81478421:      0f 94 c0                sete   %al
+ static inline void put_cred(const struct cred *_cred)
+ {
+        struct cred *cred = (struct cred *) _cred;
+
+        validate_creds(cred);
+        if (atomic_dec_and_test(&(cred)->usage))
+ ffffffff81478424:      84 c0                   test   %al,%al
+ ffffffff81478426:      74 05                   je     ffffffff8147842d <free_async+0x2d>
+                __put_cred(cred);
+ ffffffff81478428:      e8 d3 99 c1 ff          callq  ffffffff81091e00 <__put_cred>
+        kfree(as->urb->transfer_buffer);
+ ffffffff8147842d:      48 8b 43 40             mov    0x40(%rbx),%rax
+ ffffffff81478431:      48 8b 78 68             mov    0x68(%rax),%rdi
+ ffffffff81478435:      e8 a6 e1 ce ff          callq  ffffffff811665e0 <kfree>
+        kfree(as->urb->setup_packet);
+ ffffffff8147843a:      48 8b 43 40             mov    0x40(%rbx),%rax
+ ffffffff8147843e:      48 8b b8 90 00 00 00    mov    0x90(%rax),%rdi
+ ffffffff81478445:      e8 96 e1 ce ff          callq  ffffffff811665e0 <kfree>
+        usb_free_urb(as->urb);
+ ffffffff8147844a:      48 8b 7b 40             mov    0x40(%rbx),%rdi
+ ffffffff8147844e:      e8 0d 6b ff ff          callq  ffffffff8146ef60 <usb_free_urb>
+
+This bug seems to have been introduced by commit
+d178bc3a708f39cbfefc3fab37032d3f2511b4ec "user namespace: usb: make usb
+urbs user namespace aware (v2)"
+
+I'm not sure if this is right fix, but it does stop the oops.
+
+Unfortunately, the Point Grey software still refuses to work, but it's a
+closed source app, so I can't fix it.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/devio.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -249,7 +249,8 @@ static struct async *alloc_async(unsigne
+ static void free_async(struct async *as)
+ {
+       put_pid(as->pid);
+-      put_cred(as->cred);
++      if (as->cred)
++              put_cred(as->cred);
+       kfree(as->urb->transfer_buffer);
+       kfree(as->urb->setup_packet);
+       usb_free_urb(as->urb);