]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Mar 2013 18:28:59 +0000 (11:28 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Mar 2013 18:28:59 +0000 (11:28 -0700)
added patches:
acpi-rework-acpi_get_child-to-be-more-efficient.patch
clockevents-don-t-allow-dummy-broadcast-timers.patch
efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch
efivars-allow-disabling-use-as-a-pstore-backend.patch
efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch
ext4-fix-data-journal-fast-mount-umount-hang.patch
ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch
ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch
ipoib-fix-send-lockup-due-to-missed-tx-completion.patch
md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch
md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch
md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch
nfsd-fix-bad-offset-use.patch
usb-cdc-acm-fix-device-unregistration.patch
usb-ehci-fix-regression-during-bus-resume.patch
usb-ehci-fix-regression-in-qh-unlinking.patch
usb-gadget-ffs-fix-enable-multiple-instances.patch
usb-serial-fix-interface-refcounting.patch
usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch
usb-xhci-correctly-enable-interrupts.patch
usb-xhci-fix-bit-definitions-for-iman-register.patch
watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch
watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch
x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch

25 files changed:
queue-3.8/acpi-rework-acpi_get_child-to-be-more-efficient.patch [new file with mode: 0644]
queue-3.8/clockevents-don-t-allow-dummy-broadcast-timers.patch [new file with mode: 0644]
queue-3.8/efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch [new file with mode: 0644]
queue-3.8/efivars-allow-disabling-use-as-a-pstore-backend.patch [new file with mode: 0644]
queue-3.8/efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch [new file with mode: 0644]
queue-3.8/ext4-fix-data-journal-fast-mount-umount-hang.patch [new file with mode: 0644]
queue-3.8/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch [new file with mode: 0644]
queue-3.8/ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch [new file with mode: 0644]
queue-3.8/ipoib-fix-send-lockup-due-to-missed-tx-completion.patch [new file with mode: 0644]
queue-3.8/md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch [new file with mode: 0644]
queue-3.8/md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch [new file with mode: 0644]
queue-3.8/md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch [new file with mode: 0644]
queue-3.8/nfsd-fix-bad-offset-use.patch [new file with mode: 0644]
queue-3.8/series
queue-3.8/usb-cdc-acm-fix-device-unregistration.patch [new file with mode: 0644]
queue-3.8/usb-ehci-fix-regression-during-bus-resume.patch [new file with mode: 0644]
queue-3.8/usb-ehci-fix-regression-in-qh-unlinking.patch [new file with mode: 0644]
queue-3.8/usb-gadget-ffs-fix-enable-multiple-instances.patch [new file with mode: 0644]
queue-3.8/usb-serial-fix-interface-refcounting.patch [new file with mode: 0644]
queue-3.8/usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch [new file with mode: 0644]
queue-3.8/usb-xhci-correctly-enable-interrupts.patch [new file with mode: 0644]
queue-3.8/usb-xhci-fix-bit-definitions-for-iman-register.patch [new file with mode: 0644]
queue-3.8/watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch [new file with mode: 0644]
queue-3.8/watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch [new file with mode: 0644]
queue-3.8/x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch [new file with mode: 0644]

diff --git a/queue-3.8/acpi-rework-acpi_get_child-to-be-more-efficient.patch b/queue-3.8/acpi-rework-acpi_get_child-to-be-more-efficient.patch
new file mode 100644 (file)
index 0000000..e9bde1c
--- /dev/null
@@ -0,0 +1,85 @@
+From 33f767d767e9a684e9cd60704d4c049a2014c8d5 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Thu, 10 Jan 2013 13:13:49 +0100
+Subject: ACPI: Rework acpi_get_child() to be more efficient
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+
+commit 33f767d767e9a684e9cd60704d4c049a2014c8d5 upstream.
+
+Observe that acpi_get_child() doesn't need to use the helper
+struct acpi_find_child structure and change it to work without it.
+Also, using acpi_get_object_info() to get the output of _ADR for the
+given device is overkill, because that function does much more than
+just evaluating _ADR (let alone the additional memory allocation
+done by it).
+
+Moreover, acpi_get_child() doesn't need to loop any more once it has
+found a matching handle, so make it stop in that case.  To prevent
+the results from changing, make it use do_acpi_find_child() as
+a post-order callback.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: Josh Boyer <jwboyer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/acpi/glue.c |   33 ++++++++++++---------------------
+ 1 file changed, 12 insertions(+), 21 deletions(-)
+
+--- a/drivers/acpi/glue.c
++++ b/drivers/acpi/glue.c
+@@ -95,40 +95,31 @@ static int acpi_find_bridge_device(struc
+       return ret;
+ }
+-/* Get device's handler per its address under its parent */
+-struct acpi_find_child {
+-      acpi_handle handle;
+-      u64 address;
+-};
+-
+-static acpi_status
+-do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
++static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
++                                    void *addr_p, void **ret_p)
+ {
++      unsigned long long addr;
+       acpi_status status;
+-      struct acpi_device_info *info;
+-      struct acpi_find_child *find = context;
+-      status = acpi_get_object_info(handle, &info);
+-      if (ACPI_SUCCESS(status)) {
+-              if ((info->address == find->address)
+-                      && (info->valid & ACPI_VALID_ADR))
+-                      find->handle = handle;
+-              kfree(info);
++      status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
++      if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
++              *ret_p = handle;
++              return AE_CTRL_TERMINATE;
+       }
+       return AE_OK;
+ }
+ acpi_handle acpi_get_child(acpi_handle parent, u64 address)
+ {
+-      struct acpi_find_child find = { NULL, address };
++      void *ret = NULL;
+       if (!parent)
+               return NULL;
+-      acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
+-                          1, do_acpi_find_child, NULL, &find, NULL);
+-      return find.handle;
+-}
++      acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL,
++                          do_acpi_find_child, &address, &ret);
++      return (acpi_handle)ret;
++}
+ EXPORT_SYMBOL(acpi_get_child);
+ static int acpi_bind_one(struct device *dev, acpi_handle handle)
diff --git a/queue-3.8/clockevents-don-t-allow-dummy-broadcast-timers.patch b/queue-3.8/clockevents-don-t-allow-dummy-broadcast-timers.patch
new file mode 100644 (file)
index 0000000..7a6e990
--- /dev/null
@@ -0,0 +1,41 @@
+From a7dc19b8652c862d5b7c4d2339bd3c428bd29c4a Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Thu, 7 Mar 2013 15:09:24 +0000
+Subject: clockevents: Don't allow dummy broadcast timers
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit a7dc19b8652c862d5b7c4d2339bd3c428bd29c4a upstream.
+
+Currently tick_check_broadcast_device doesn't reject clock_event_devices
+with CLOCK_EVT_FEAT_DUMMY, and may select them in preference to real
+hardware if they have a higher rating value. In this situation, the
+dummy timer is responsible for broadcasting to itself, and the core
+clockevents code may attempt to call non-existent callbacks for
+programming the dummy, eventually leading to a panic.
+
+This patch makes tick_check_broadcast_device always reject dummy timers,
+preventing this problem.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: Jon Medhurst (Tixy) <tixy@linaro.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/time/tick-broadcast.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kernel/time/tick-broadcast.c
++++ b/kernel/time/tick-broadcast.c
+@@ -66,7 +66,8 @@ static void tick_broadcast_start_periodi
+  */
+ int tick_check_broadcast_device(struct clock_event_device *dev)
+ {
+-      if ((tick_broadcast_device.evtdev &&
++      if ((dev->features & CLOCK_EVT_FEAT_DUMMY) ||
++          (tick_broadcast_device.evtdev &&
+            tick_broadcast_device.evtdev->rating >= dev->rating) ||
+            (dev->features & CLOCK_EVT_FEAT_C3STOP))
+               return 0;
diff --git a/queue-3.8/efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch b/queue-3.8/efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch
new file mode 100644 (file)
index 0000000..e01deff
--- /dev/null
@@ -0,0 +1,76 @@
+From ec0971ba5372a4dfa753f232449d23a8fd98490e Mon Sep 17 00:00:00 2001
+From: Seth Forshee <seth.forshee@canonical.com>
+Date: Mon, 11 Mar 2013 16:17:50 -0500
+Subject: efivars: Add module parameter to disable use as a pstore backend
+
+From: Seth Forshee <seth.forshee@canonical.com>
+
+commit ec0971ba5372a4dfa753f232449d23a8fd98490e upstream.
+
+We know that with some firmware implementations writing too much data to
+UEFI variables can lead to bricking machines. Recent changes attempt to
+address this issue, but for some it may still be prudent to avoid
+writing large amounts of data until the solution has been proven on a
+wide variety of hardware.
+
+Crash dumps or other data from pstore can potentially be a large data
+source. Add a pstore_module parameter to efivars to allow disabling its
+use as a backend for pstore. Also add a config option,
+CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE, to allow setting the default
+value of this paramter to true (i.e. disabled by default).
+
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+Cc: Josh Boyer <jwboyer@redhat.com>
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Cc: Seiji Aguchi <seiji.aguchi@hds.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/Kconfig   |    9 +++++++++
+ drivers/firmware/efivars.c |    8 +++++++-
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/firmware/Kconfig
++++ b/drivers/firmware/Kconfig
+@@ -62,6 +62,15 @@ config EFI_VARS_PSTORE
+         will allow writing console messages, crash dumps, or anything
+         else supported by pstore to EFI variables.
++config EFI_VARS_PSTORE_DEFAULT_DISABLE
++      bool "Disable using efivars as a pstore backend by default"
++      depends on EFI_VARS_PSTORE
++      default n
++      help
++        Saying Y here will disable the use of efivars as a storage
++        backend for pstore by default. This setting can be overridden
++        using the efivars module's pstore_disable parameter.
++
+ config EFI_PCDP
+       bool "Console device selection via EFI PCDP or HCDP table"
+       depends on ACPI && EFI && IA64
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -103,6 +103,11 @@ MODULE_VERSION(EFIVARS_VERSION);
+  */
+ #define GUID_LEN 36
++static bool efivars_pstore_disable =
++      IS_ENABLED(EFI_VARS_PSTORE_DEFAULT_DISABLE);
++
++module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
++
+ /*
+  * The maximum size of VariableName + Data = 1024
+  * Therefore, it's reasonable to save that much
+@@ -1926,7 +1931,8 @@ int register_efivars(struct efivars *efi
+       if (error)
+               unregister_efivars(efivars);
+-      efivar_pstore_register(efivars);
++      if (!efivars_pstore_disable)
++              efivar_pstore_register(efivars);
+       register_filesystem(&efivarfs_type);
diff --git a/queue-3.8/efivars-allow-disabling-use-as-a-pstore-backend.patch b/queue-3.8/efivars-allow-disabling-use-as-a-pstore-backend.patch
new file mode 100644 (file)
index 0000000..c11c1bb
--- /dev/null
@@ -0,0 +1,141 @@
+From ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef Mon Sep 17 00:00:00 2001
+From: Seth Forshee <seth.forshee@canonical.com>
+Date: Thu, 7 Mar 2013 11:40:17 -0600
+Subject: efivars: Allow disabling use as a pstore backend
+
+From: Seth Forshee <seth.forshee@canonical.com>
+
+commit ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef upstream.
+
+Add a new option, CONFIG_EFI_VARS_PSTORE, which can be set to N to
+avoid using efivars as a backend to pstore, as some users may want to
+compile out the code completely.
+
+Set the default to Y to maintain backwards compatability, since this
+feature has always been enabled until now.
+
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+Cc: Josh Boyer <jwboyer@redhat.com>
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Cc: Seiji Aguchi <seiji.aguchi@hds.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/Kconfig   |    9 ++++++
+ drivers/firmware/efivars.c |   64 ++++++++++++++-------------------------------
+ 2 files changed, 29 insertions(+), 44 deletions(-)
+
+--- a/drivers/firmware/Kconfig
++++ b/drivers/firmware/Kconfig
+@@ -53,6 +53,15 @@ config EFI_VARS
+         Subsequent efibootmgr releases may be found at:
+         <http://linux.dell.com/efibootmgr>
++config EFI_VARS_PSTORE
++      bool "Register efivars backend for pstore"
++      depends on EFI_VARS && PSTORE
++      default y
++      help
++        Say Y here to enable use efivars as a backend to pstore. This
++        will allow writing console messages, crash dumps, or anything
++        else supported by pstore to EFI variables.
++
+ config EFI_PCDP
+       bool "Console device selection via EFI PCDP or HCDP table"
+       depends on ACPI && EFI && IA64
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -1301,9 +1301,7 @@ static const struct inode_operations efi
+       .create = efivarfs_create,
+ };
+-static struct pstore_info efi_pstore_info;
+-
+-#ifdef CONFIG_PSTORE
++#ifdef CONFIG_EFI_VARS_PSTORE
+ static int efi_pstore_open(struct pstore_info *psi)
+ {
+@@ -1500,38 +1498,6 @@ static int efi_pstore_erase(enum pstore_
+       return 0;
+ }
+-#else
+-static int efi_pstore_open(struct pstore_info *psi)
+-{
+-      return 0;
+-}
+-
+-static int efi_pstore_close(struct pstore_info *psi)
+-{
+-      return 0;
+-}
+-
+-static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count,
+-                             struct timespec *timespec,
+-                             char **buf, struct pstore_info *psi)
+-{
+-      return -1;
+-}
+-
+-static int efi_pstore_write(enum pstore_type_id type,
+-              enum kmsg_dump_reason reason, u64 *id,
+-              unsigned int part, int count, size_t size,
+-              struct pstore_info *psi)
+-{
+-      return 0;
+-}
+-
+-static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
+-                          struct timespec time, struct pstore_info *psi)
+-{
+-      return 0;
+-}
+-#endif
+ static struct pstore_info efi_pstore_info = {
+       .owner          = THIS_MODULE,
+@@ -1543,6 +1509,24 @@ static struct pstore_info efi_pstore_inf
+       .erase          = efi_pstore_erase,
+ };
++static void efivar_pstore_register(struct efivars *efivars)
++{
++      efivars->efi_pstore_info = efi_pstore_info;
++      efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
++      if (efivars->efi_pstore_info.buf) {
++              efivars->efi_pstore_info.bufsize = 1024;
++              efivars->efi_pstore_info.data = efivars;
++              spin_lock_init(&efivars->efi_pstore_info.buf_lock);
++              pstore_register(&efivars->efi_pstore_info);
++      }
++}
++#else
++static void efivar_pstore_register(struct efivars *efivars)
++{
++      return;
++}
++#endif
++
+ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buf, loff_t pos, size_t count)
+@@ -1942,15 +1926,7 @@ int register_efivars(struct efivars *efi
+       if (error)
+               unregister_efivars(efivars);
+-      efivars->efi_pstore_info = efi_pstore_info;
+-
+-      efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
+-      if (efivars->efi_pstore_info.buf) {
+-              efivars->efi_pstore_info.bufsize = 1024;
+-              efivars->efi_pstore_info.data = efivars;
+-              spin_lock_init(&efivars->efi_pstore_info.buf_lock);
+-              pstore_register(&efivars->efi_pstore_info);
+-      }
++      efivar_pstore_register(efivars);
+       register_filesystem(&efivarfs_type);
diff --git a/queue-3.8/efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch b/queue-3.8/efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch
new file mode 100644 (file)
index 0000000..a81af2e
--- /dev/null
@@ -0,0 +1,31 @@
+From ca0ba26fbbd2d81c43085df49ce0abfe34535a90 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 22 Mar 2013 19:56:51 +0000
+Subject: efivars: Fix check for CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit ca0ba26fbbd2d81c43085df49ce0abfe34535a90 upstream.
+
+The 'CONFIG_' prefix is not implicit in IS_ENABLED().
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Seth Forshee <seth.forshee@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efivars.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -104,7 +104,7 @@ MODULE_VERSION(EFIVARS_VERSION);
+ #define GUID_LEN 36
+ static bool efivars_pstore_disable =
+-      IS_ENABLED(EFI_VARS_PSTORE_DEFAULT_DISABLE);
++      IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
+ module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
diff --git a/queue-3.8/ext4-fix-data-journal-fast-mount-umount-hang.patch b/queue-3.8/ext4-fix-data-journal-fast-mount-umount-hang.patch
new file mode 100644 (file)
index 0000000..c696bdb
--- /dev/null
@@ -0,0 +1,75 @@
+From 2b405bfa84063bfa35621d2d6879f52693c614b0 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 20 Mar 2013 09:42:11 -0400
+Subject: ext4: fix data=journal fast mount/umount hang
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 2b405bfa84063bfa35621d2d6879f52693c614b0 upstream.
+
+In data=journal mode, if we unmount the file system before a
+transaction has a chance to complete, when the journal inode is being
+evicted, we can end up calling into jbd2_log_wait_commit() for the
+last transaction, after the journalling machinery has been shut down.
+
+Arguably we should adjust ext4_should_journal_data() to return FALSE
+for the journal inode, but the only place it matters is
+ext4_evict_inode(), and so to save a bit of CPU time, and to make the
+patch much more obviously correct by inspection(tm), we'll fix it by
+explicitly not trying to waiting for a journal commit when we are
+evicting the journal inode, since it's guaranteed to never succeed in
+this case.
+
+This can be easily replicated via:
+
+     mount -t ext4 -o data=journal /dev/vdb /vdb ; umount /vdb
+
+------------[ cut here ]------------
+WARNING: at /usr/projects/linux/ext4/fs/jbd2/journal.c:542 __jbd2_log_start_commit+0xba/0xcd()
+Hardware name: Bochs
+JBD2: bad log_start_commit: 3005630206 3005630206 0 0
+Modules linked in:
+Pid: 2909, comm: umount Not tainted 3.8.0-rc3 #1020
+Call Trace:
+ [<c015c0ef>] warn_slowpath_common+0x68/0x7d
+ [<c02b7e7d>] ? __jbd2_log_start_commit+0xba/0xcd
+ [<c015c177>] warn_slowpath_fmt+0x2b/0x2f
+ [<c02b7e7d>] __jbd2_log_start_commit+0xba/0xcd
+ [<c02b8075>] jbd2_log_start_commit+0x24/0x34
+ [<c0279ed5>] ext4_evict_inode+0x71/0x2e3
+ [<c021f0ec>] evict+0x94/0x135
+ [<c021f9aa>] iput+0x10a/0x110
+ [<c02b7836>] jbd2_journal_destroy+0x190/0x1ce
+ [<c0175284>] ? bit_waitqueue+0x50/0x50
+ [<c028d23f>] ext4_put_super+0x52/0x294
+ [<c020efe3>] generic_shutdown_super+0x48/0xb4
+ [<c020f071>] kill_block_super+0x22/0x60
+ [<c020f3e0>] deactivate_locked_super+0x22/0x49
+ [<c020f5d6>] deactivate_super+0x30/0x33
+ [<c0222795>] mntput_no_expire+0x107/0x10c
+ [<c02233a7>] sys_umount+0x2cf/0x2e0
+ [<c02233ca>] sys_oldumount+0x12/0x14
+ [<c08096b8>] syscall_call+0x7/0xb
+---[ end trace 6a954cc790501c1f ]---
+jbd2_log_wait_commit: error: j_commit_request=-1289337090, tid=0
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -211,7 +211,8 @@ void ext4_evict_inode(struct inode *inod
+                * don't use page cache.
+                */
+               if (ext4_should_journal_data(inode) &&
+-                  (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
++                  (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
++                  inode->i_ino != EXT4_JOURNAL_INO) {
+                       journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
+                       tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;
diff --git a/queue-3.8/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch b/queue-3.8/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch
new file mode 100644 (file)
index 0000000..af05f41
--- /dev/null
@@ -0,0 +1,130 @@
+From 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Mon, 11 Mar 2013 23:39:59 -0400
+Subject: ext4: use atomic64_t for the per-flexbg free_clusters count
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 upstream.
+
+A user who was using a 8TB+ file system and with a very large flexbg
+size (> 65536) could cause the atomic_t used in the struct flex_groups
+to overflow.  This was detected by PaX security patchset:
+
+http://forums.grsecurity.net/viewtopic.php?f=3&t=3289&p=12551#p12551
+
+This bug was introduced in commit 9f24e4208f7e, so it's been around
+since 2.6.30.  :-(
+
+Fix this by using an atomic64_t for struct orlav_stats's
+free_clusters.
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Reviewed-by: Lukas Czerner <lczerner@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ext4.h    |    6 +++---
+ fs/ext4/ialloc.c  |    4 ++--
+ fs/ext4/mballoc.c |   12 ++++++------
+ fs/ext4/resize.c  |    4 ++--
+ fs/ext4/super.c   |    4 ++--
+ 5 files changed, 15 insertions(+), 15 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -338,9 +338,9 @@ struct ext4_group_desc
+  */
+ struct flex_groups {
+-      atomic_t free_inodes;
+-      atomic_t free_clusters;
+-      atomic_t used_dirs;
++      atomic64_t      free_clusters;
++      atomic_t        free_inodes;
++      atomic_t        used_dirs;
+ };
+ #define EXT4_BG_INODE_UNINIT  0x0001 /* Inode table/bitmap not in use */
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -324,8 +324,8 @@ error_return:
+ }
+ struct orlov_stats {
++      __u64 free_clusters;
+       __u32 free_inodes;
+-      __u32 free_clusters;
+       __u32 used_dirs;
+ };
+@@ -342,7 +342,7 @@ static void get_orlov_stats(struct super
+       if (flex_size > 1) {
+               stats->free_inodes = atomic_read(&flex_group[g].free_inodes);
+-              stats->free_clusters = atomic_read(&flex_group[g].free_clusters);
++              stats->free_clusters = atomic64_read(&flex_group[g].free_clusters);
+               stats->used_dirs = atomic_read(&flex_group[g].used_dirs);
+               return;
+       }
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2829,8 +2829,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
+       if (sbi->s_log_groups_per_flex) {
+               ext4_group_t flex_group = ext4_flex_group(sbi,
+                                                         ac->ac_b_ex.fe_group);
+-              atomic_sub(ac->ac_b_ex.fe_len,
+-                         &sbi->s_flex_groups[flex_group].free_clusters);
++              atomic64_sub(ac->ac_b_ex.fe_len,
++                           &sbi->s_flex_groups[flex_group].free_clusters);
+       }
+       err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
+@@ -4691,8 +4691,8 @@ do_more:
+       if (sbi->s_log_groups_per_flex) {
+               ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
+-              atomic_add(count_clusters,
+-                         &sbi->s_flex_groups[flex_group].free_clusters);
++              atomic64_add(count_clusters,
++                           &sbi->s_flex_groups[flex_group].free_clusters);
+       }
+       ext4_mb_unload_buddy(&e4b);
+@@ -4836,8 +4836,8 @@ int ext4_group_add_blocks(handle_t *hand
+       if (sbi->s_log_groups_per_flex) {
+               ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
+-              atomic_add(EXT4_NUM_B2C(sbi, blocks_freed),
+-                         &sbi->s_flex_groups[flex_group].free_clusters);
++              atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed),
++                           &sbi->s_flex_groups[flex_group].free_clusters);
+       }
+       ext4_mb_unload_buddy(&e4b);
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1360,8 +1360,8 @@ static void ext4_update_super(struct sup
+           sbi->s_log_groups_per_flex) {
+               ext4_group_t flex_group;
+               flex_group = ext4_flex_group(sbi, group_data[0].group);
+-              atomic_add(EXT4_NUM_B2C(sbi, free_blocks),
+-                         &sbi->s_flex_groups[flex_group].free_clusters);
++              atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
++                           &sbi->s_flex_groups[flex_group].free_clusters);
+               atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
+                          &sbi->s_flex_groups[flex_group].free_inodes);
+       }
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1979,8 +1979,8 @@ static int ext4_fill_flex_info(struct su
+               flex_group = ext4_flex_group(sbi, i);
+               atomic_add(ext4_free_inodes_count(sb, gdp),
+                          &sbi->s_flex_groups[flex_group].free_inodes);
+-              atomic_add(ext4_free_group_clusters(sb, gdp),
+-                         &sbi->s_flex_groups[flex_group].free_clusters);
++              atomic64_add(ext4_free_group_clusters(sb, gdp),
++                           &sbi->s_flex_groups[flex_group].free_clusters);
+               atomic_add(ext4_used_dirs_count(sb, gdp),
+                          &sbi->s_flex_groups[flex_group].used_dirs);
+       }
diff --git a/queue-3.8/ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch b/queue-3.8/ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch
new file mode 100644 (file)
index 0000000..bd03160
--- /dev/null
@@ -0,0 +1,42 @@
+From 4f42f80a8f08d4c3f52c4267361241885d5dee3a Mon Sep 17 00:00:00 2001
+From: Lukas Czerner <lczerner@redhat.com>
+Date: Tue, 12 Mar 2013 12:40:04 -0400
+Subject: ext4: use s_extent_max_zeroout_kb value as number of kb
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+commit 4f42f80a8f08d4c3f52c4267361241885d5dee3a upstream.
+
+Currently when converting extent to initialized, we have to decide
+whether to zeroout part/all of the uninitialized extent in order to
+avoid extent tree growing rapidly.
+
+The decision is made by comparing the size of the extent with the
+configurable value s_extent_max_zeroout_kb which is in kibibytes units.
+
+However when converting it to number of blocks we currently use it as it
+was in bytes. This is obviously bug and it will result in ext4 _never_
+zeroout extents, but rather always split and convert parts to
+initialized while leaving the rest uninitialized in default setting.
+
+Fix this by using s_extent_max_zeroout_kb as kibibytes.
+
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/extents.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3278,7 +3278,7 @@ static int ext4_ext_convert_to_initializ
+       if (EXT4_EXT_MAY_ZEROOUT & split_flag)
+               max_zeroout = sbi->s_extent_max_zeroout_kb >>
+-                      inode->i_sb->s_blocksize_bits;
++                      (inode->i_sb->s_blocksize_bits - 10);
+       /* If extent is less than s_max_zeroout_kb, zeroout directly */
+       if (max_zeroout && (ee_len <= max_zeroout)) {
diff --git a/queue-3.8/ipoib-fix-send-lockup-due-to-missed-tx-completion.patch b/queue-3.8/ipoib-fix-send-lockup-due-to-missed-tx-completion.patch
new file mode 100644 (file)
index 0000000..5db4eac
--- /dev/null
@@ -0,0 +1,51 @@
+From 1ee9e2aa7b31427303466776f455d43e5e3c9275 Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Date: Tue, 26 Feb 2013 15:46:27 +0000
+Subject: IPoIB: Fix send lockup due to missed TX completion
+
+From: Mike Marciniszyn <mike.marciniszyn@intel.com>
+
+commit 1ee9e2aa7b31427303466776f455d43e5e3c9275 upstream.
+
+Commit f0dc117abdfa ("IPoIB: Fix TX queue lockup with mixed UD/CM
+traffic") attempts to solve an issue where unprocessed UD send
+completions can deadlock the netdev.
+
+The patch doesn't fully resolve the issue because if more than half
+the tx_outstanding's were UD and all of the destinations are RC
+reachable, arming the CQ doesn't solve the issue.
+
+This patch uses the IB_CQ_REPORT_MISSED_EVENTS on the
+ib_req_notify_cq().  If the rc is above 0, the UD send cq completion
+callback is called directly to re-arm the send completion timer.
+
+This issue is seen in very large parallel filesystem deployments
+and the patch has been shown to correct the issue.
+
+Reviewed-by: Dean Luick <dean.luick@intel.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/ulp/ipoib/ipoib_cm.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+@@ -758,9 +758,13 @@ void ipoib_cm_send(struct net_device *de
+               if (++priv->tx_outstanding == ipoib_sendq_size) {
+                       ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
+                                 tx->qp->qp_num);
+-                      if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
+-                              ipoib_warn(priv, "request notify on send CQ failed\n");
+                       netif_stop_queue(dev);
++                      rc = ib_req_notify_cq(priv->send_cq,
++                              IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
++                      if (rc < 0)
++                              ipoib_warn(priv, "request notify on send CQ failed\n");
++                      else if (rc)
++                              ipoib_send_comp_handler(priv->send_cq, dev);
+               }
+       }
+ }
diff --git a/queue-3.8/md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch b/queue-3.8/md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch
new file mode 100644 (file)
index 0000000..110681b
--- /dev/null
@@ -0,0 +1,105 @@
+From e3620a3ad52609f64a2402e4b59300afb4b83b77 Mon Sep 17 00:00:00 2001
+From: Jonathan Brassow <jbrassow@redhat.com>
+Date: Thu, 7 Mar 2013 16:22:01 -0600
+Subject: MD RAID5: Avoid accessing gendisk or queue structs when not available
+
+From: Jonathan Brassow <jbrassow@redhat.com>
+
+commit e3620a3ad52609f64a2402e4b59300afb4b83b77 upstream.
+
+MD RAID5:  Fix kernel oops when RAID4/5/6 is used via device-mapper
+
+Commit a9add5d (v3.8-rc1) added blktrace calls to the RAID4/5/6 driver.
+However, when device-mapper is used to create RAID4/5/6 arrays, the
+mddev->gendisk and mddev->queue fields are not setup.  Therefore, calling
+things like trace_block_bio_remap will cause a kernel oops.  This patch
+conditionalizes those calls on whether the proper fields exist to make
+the calls.  (Device-mapper will call trace_block_bio_remap on its own.)
+
+This patch is suitable for the 3.8.y stable kernel.
+
+Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/raid5.c |   33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -674,9 +674,11 @@ static void ops_run_io(struct stripe_hea
+                       bi->bi_next = NULL;
+                       if (rrdev)
+                               set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
+-                      trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
+-                                            bi, disk_devt(conf->mddev->gendisk),
+-                                            sh->dev[i].sector);
++
++                      if (conf->mddev->gendisk)
++                              trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
++                                                    bi, disk_devt(conf->mddev->gendisk),
++                                                    sh->dev[i].sector);
+                       generic_make_request(bi);
+               }
+               if (rrdev) {
+@@ -704,9 +706,10 @@ static void ops_run_io(struct stripe_hea
+                       rbi->bi_io_vec[0].bv_offset = 0;
+                       rbi->bi_size = STRIPE_SIZE;
+                       rbi->bi_next = NULL;
+-                      trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
+-                                            rbi, disk_devt(conf->mddev->gendisk),
+-                                            sh->dev[i].sector);
++                      if (conf->mddev->gendisk)
++                              trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
++                                                    rbi, disk_devt(conf->mddev->gendisk),
++                                                    sh->dev[i].sector);
+                       generic_make_request(rbi);
+               }
+               if (!rdev && !rrdev) {
+@@ -2871,8 +2874,10 @@ static void handle_stripe_dirtying(struc
+       set_bit(STRIPE_HANDLE, &sh->state);
+       if (rmw < rcw && rmw > 0) {
+               /* prefer read-modify-write, but need to get some data */
+-              blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d",
+-                                (unsigned long long)sh->sector, rmw);
++              if (conf->mddev->queue)
++                      blk_add_trace_msg(conf->mddev->queue,
++                                        "raid5 rmw %llu %d",
++                                        (unsigned long long)sh->sector, rmw);
+               for (i = disks; i--; ) {
+                       struct r5dev *dev = &sh->dev[i];
+                       if ((dev->towrite || i == sh->pd_idx) &&
+@@ -2922,7 +2927,7 @@ static void handle_stripe_dirtying(struc
+                               }
+                       }
+               }
+-              if (rcw)
++              if (rcw && conf->mddev->queue)
+                       blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d",
+                                         (unsigned long long)sh->sector,
+                                         rcw, qread, test_bit(STRIPE_DELAYED, &sh->state));
+@@ -4029,9 +4034,10 @@ static int chunk_aligned_read(struct mdd
+               atomic_inc(&conf->active_aligned_reads);
+               spin_unlock_irq(&conf->device_lock);
+-              trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
+-                                    align_bi, disk_devt(mddev->gendisk),
+-                                    raid_bio->bi_sector);
++              if (mddev->gendisk)
++                      trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
++                                            align_bi, disk_devt(mddev->gendisk),
++                                            raid_bio->bi_sector);
+               generic_make_request(align_bi);
+               return 1;
+       } else {
+@@ -4125,7 +4131,8 @@ static void raid5_unplug(struct blk_plug
+               }
+               spin_unlock_irq(&conf->device_lock);
+       }
+-      trace_block_unplug(mddev->queue, cnt, !from_schedule);
++      if (mddev->queue)
++              trace_block_unplug(mddev->queue, cnt, !from_schedule);
+       kfree(cb);
+ }
diff --git a/queue-3.8/md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch b/queue-3.8/md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch
new file mode 100644 (file)
index 0000000..679c880
--- /dev/null
@@ -0,0 +1,157 @@
+From f8dfcffd0472a0f353f34a567ad3f53568914d04 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Tue, 12 Mar 2013 12:18:06 +1100
+Subject: md/raid5: ensure sync and DISCARD don't happen at the same time.
+
+From: NeilBrown <neilb@suse.de>
+
+commit f8dfcffd0472a0f353f34a567ad3f53568914d04 upstream.
+
+A number of problems can occur due to races between
+resync/recovery and discard.
+
+- if sync_request calls handle_stripe() while a discard is
+  happening on the stripe, it might call handle_stripe_clean_event
+  before all of the individual discard requests have completed
+  (so some devices are still locked, but not all).
+  Since commit ca64cae96037de16e4af92678814f5d4bf0c1c65
+     md/raid5: Make sure we clear R5_Discard when discard is finished.
+  this will cause R5_Discard to be cleared for the parity device,
+  so handle_stripe_clean_event() will not be called when the other
+  devices do become unlocked, so their ->written will not be cleared.
+  This ultimately leads to a WARN_ON in init_stripe and a lock-up.
+
+- If handle_stripe_clean_event() does clear R5_UPTODATE at an awkward
+  time for resync, it can lead to s->uptodate being less than disks
+  in handle_parity_checks5(), which triggers a BUG (because it is
+  one).
+
+So:
+ - keep R5_Discard on the parity device until all other devices have
+   completed their discard request
+ - make sure we don't try to have a 'discard' and a 'sync' action at
+   the same time.
+   This involves a new stripe flag to we know when a 'discard' is
+   happening, and the use of R5_Overlap on the parity disk so when a
+   discard is wanted while a sync is active, so we know to wake up
+   the discard at the appropriate time.
+
+Discard support for RAID5 was added in 3.7, so this is suitable for
+any -stable kernel since 3.7.
+
+Reported-by: Jes Sorensen <Jes.Sorensen@redhat.com>
+Tested-by: Jes Sorensen <Jes.Sorensen@redhat.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/raid5.c |   45 +++++++++++++++++++++++++++++++++++++++------
+ drivers/md/raid5.h |    1 +
+ 2 files changed, 40 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -2612,6 +2612,8 @@ handle_failed_sync(struct r5conf *conf,
+       int i;
+       clear_bit(STRIPE_SYNCING, &sh->state);
++      if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags))
++              wake_up(&conf->wait_for_overlap);
+       s->syncing = 0;
+       s->replacing = 0;
+       /* There is nothing more to do for sync/check/repair.
+@@ -2785,6 +2787,7 @@ static void handle_stripe_clean_event(st
+ {
+       int i;
+       struct r5dev *dev;
++      int discard_pending = 0;
+       for (i = disks; i--; )
+               if (sh->dev[i].written) {
+@@ -2813,9 +2816,23 @@ static void handle_stripe_clean_event(st
+                                               STRIPE_SECTORS,
+                                        !test_bit(STRIPE_DEGRADED, &sh->state),
+                                               0);
+-                      }
+-              } else if (test_bit(R5_Discard, &sh->dev[i].flags))
+-                      clear_bit(R5_Discard, &sh->dev[i].flags);
++                      } else if (test_bit(R5_Discard, &dev->flags))
++                              discard_pending = 1;
++              }
++      if (!discard_pending &&
++          test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) {
++              clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags);
++              clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
++              if (sh->qd_idx >= 0) {
++                      clear_bit(R5_Discard, &sh->dev[sh->qd_idx].flags);
++                      clear_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags);
++              }
++              /* now that discard is done we can proceed with any sync */
++              clear_bit(STRIPE_DISCARD, &sh->state);
++              if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
++                      set_bit(STRIPE_HANDLE, &sh->state);
++
++      }
+       if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
+               if (atomic_dec_and_test(&conf->pending_full_writes))
+@@ -3467,9 +3484,15 @@ static void handle_stripe(struct stripe_
+               return;
+       }
+-      if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
+-              set_bit(STRIPE_SYNCING, &sh->state);
+-              clear_bit(STRIPE_INSYNC, &sh->state);
++      if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
++              spin_lock(&sh->stripe_lock);
++              /* Cannot process 'sync' concurrently with 'discard' */
++              if (!test_bit(STRIPE_DISCARD, &sh->state) &&
++                  test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
++                      set_bit(STRIPE_SYNCING, &sh->state);
++                      clear_bit(STRIPE_INSYNC, &sh->state);
++              }
++              spin_unlock(&sh->stripe_lock);
+       }
+       clear_bit(STRIPE_DELAYED, &sh->state);
+@@ -3629,6 +3652,8 @@ static void handle_stripe(struct stripe_
+           test_bit(STRIPE_INSYNC, &sh->state)) {
+               md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
+               clear_bit(STRIPE_SYNCING, &sh->state);
++              if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags))
++                      wake_up(&conf->wait_for_overlap);
+       }
+       /* If the failed drives are just a ReadError, then we might need
+@@ -4195,6 +4220,13 @@ static void make_discard_request(struct
+               sh = get_active_stripe(conf, logical_sector, 0, 0, 0);
+               prepare_to_wait(&conf->wait_for_overlap, &w,
+                               TASK_UNINTERRUPTIBLE);
++              set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
++              if (test_bit(STRIPE_SYNCING, &sh->state)) {
++                      release_stripe(sh);
++                      schedule();
++                      goto again;
++              }
++              clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
+               spin_lock_irq(&sh->stripe_lock);
+               for (d = 0; d < conf->raid_disks; d++) {
+                       if (d == sh->pd_idx || d == sh->qd_idx)
+@@ -4207,6 +4239,7 @@ static void make_discard_request(struct
+                               goto again;
+                       }
+               }
++              set_bit(STRIPE_DISCARD, &sh->state);
+               finish_wait(&conf->wait_for_overlap, &w);
+               for (d = 0; d < conf->raid_disks; d++) {
+                       if (d == sh->pd_idx || d == sh->qd_idx)
+--- a/drivers/md/raid5.h
++++ b/drivers/md/raid5.h
+@@ -323,6 +323,7 @@ enum {
+       STRIPE_COMPUTE_RUN,
+       STRIPE_OPS_REQ_PENDING,
+       STRIPE_ON_UNPLUG_LIST,
++      STRIPE_DISCARD,
+ };
+ /*
diff --git a/queue-3.8/md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch b/queue-3.8/md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch
new file mode 100644 (file)
index 0000000..1a04c02
--- /dev/null
@@ -0,0 +1,100 @@
+From ce7d363aaf1e28be8406a2976220944ca487e8ca Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Mon, 4 Mar 2013 12:37:14 +1100
+Subject: md/raid5: schedule_construction should abort if nothing to do.
+
+From: NeilBrown <neilb@suse.de>
+
+commit ce7d363aaf1e28be8406a2976220944ca487e8ca upstream.
+
+Since commit 1ed850f356a0a422013846b5291acff08815008b
+    md/raid5: make sure to_read and to_write never go negative.
+
+It has been possible for handle_stripe_dirtying to be called
+when there isn't actually any work to do.
+It then calls schedule_reconstruction() which will set R5_LOCKED
+on the parity block(s) even when nothing else is happening.
+This then causes problems in do_release_stripe().
+
+So add checks to schedule_reconstruction() so that if it doesn't
+find anything to do, it just aborts.
+
+This bug was introduced in v3.7, so the patch is suitable
+for -stable kernels since then.
+
+Reported-by: majianpeng <majianpeng@gmail.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/raid5.c |   38 ++++++++++++++++++++++----------------
+ 1 file changed, 22 insertions(+), 16 deletions(-)
+
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -2319,17 +2319,6 @@ schedule_reconstruction(struct stripe_he
+       int level = conf->level;
+       if (rcw) {
+-              /* if we are not expanding this is a proper write request, and
+-               * there will be bios with new data to be drained into the
+-               * stripe cache
+-               */
+-              if (!expand) {
+-                      sh->reconstruct_state = reconstruct_state_drain_run;
+-                      set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
+-              } else
+-                      sh->reconstruct_state = reconstruct_state_run;
+-
+-              set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
+               for (i = disks; i--; ) {
+                       struct r5dev *dev = &sh->dev[i];
+@@ -2342,6 +2331,21 @@ schedule_reconstruction(struct stripe_he
+                               s->locked++;
+                       }
+               }
++              /* if we are not expanding this is a proper write request, and
++               * there will be bios with new data to be drained into the
++               * stripe cache
++               */
++              if (!expand) {
++                      if (!s->locked)
++                              /* False alarm, nothing to do */
++                              return;
++                      sh->reconstruct_state = reconstruct_state_drain_run;
++                      set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
++              } else
++                      sh->reconstruct_state = reconstruct_state_run;
++
++              set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
++
+               if (s->locked + conf->max_degraded == disks)
+                       if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state))
+                               atomic_inc(&conf->pending_full_writes);
+@@ -2350,11 +2354,6 @@ schedule_reconstruction(struct stripe_he
+               BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) ||
+                       test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags)));
+-              sh->reconstruct_state = reconstruct_state_prexor_drain_run;
+-              set_bit(STRIPE_OP_PREXOR, &s->ops_request);
+-              set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
+-              set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
+-
+               for (i = disks; i--; ) {
+                       struct r5dev *dev = &sh->dev[i];
+                       if (i == pd_idx)
+@@ -2369,6 +2368,13 @@ schedule_reconstruction(struct stripe_he
+                               s->locked++;
+                       }
+               }
++              if (!s->locked)
++                      /* False alarm - nothing to do */
++                      return;
++              sh->reconstruct_state = reconstruct_state_prexor_drain_run;
++              set_bit(STRIPE_OP_PREXOR, &s->ops_request);
++              set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
++              set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
+       }
+       /* keep the parity disk(s) locked while asynchronous operations
diff --git a/queue-3.8/nfsd-fix-bad-offset-use.patch b/queue-3.8/nfsd-fix-bad-offset-use.patch
new file mode 100644 (file)
index 0000000..26c8138
--- /dev/null
@@ -0,0 +1,46 @@
+From e49dbbf3e770aa590a8a464ac4978a09027060b9 Mon Sep 17 00:00:00 2001
+From: Kent Overstreet <koverstreet@google.com>
+Date: Fri, 22 Mar 2013 11:18:24 -0700
+Subject: nfsd: fix bad offset use
+
+From: Kent Overstreet <koverstreet@google.com>
+
+commit e49dbbf3e770aa590a8a464ac4978a09027060b9 upstream.
+
+vfs_writev() updates the offset argument - but the code then passes the
+offset to vfs_fsync_range(). Since offset now points to the offset after
+what was just written, this is probably not what was intended
+
+Introduced by face15025ffdf664de95e86ae831544154d26c9c "nfsd: use
+vfs_fsync_range(), not O_SYNC, for stable writes".
+
+Signed-off-by: Kent Overstreet <koverstreet@google.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Eric W. Biederman" <ebiederm@xmission.com>
+Reviewed-by: Zach Brown <zab@redhat.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/vfs.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1013,6 +1013,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
+       int                     host_err;
+       int                     stable = *stablep;
+       int                     use_wgather;
++      loff_t                  pos = offset;
+       dentry = file->f_path.dentry;
+       inode = dentry->d_inode;
+@@ -1025,7 +1026,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
+       /* Write the data. */
+       oldfs = get_fs(); set_fs(KERNEL_DS);
+-      host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
++      host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos);
+       set_fs(oldfs);
+       if (host_err < 0)
+               goto out_nfserr;
index 4a703cceeb8f6b5e82e9c29743a5ae5a638f719d..6b10af9f99a340afdae952f3ded400faa00459df 100644 (file)
@@ -66,3 +66,27 @@ cifs-delay-super-block-destruction-until-all-cifsfileinfo-objects-are-gone.patch
 cifs-ignore-everything-in-spnego-blob-after-mechtypes.patch
 jbd2-fix-use-after-free-in-jbd2_journal_dirty_metadata.patch
 ext4-fix-the-wrong-number-of-the-allocated-blocks-in-ext4_split_extent.patch
+usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch
+ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch
+ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch
+ext4-fix-data-journal-fast-mount-umount-hang.patch
+ipoib-fix-send-lockup-due-to-missed-tx-completion.patch
+watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch
+watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch
+md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch
+md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch
+md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch
+nfsd-fix-bad-offset-use.patch
+clockevents-don-t-allow-dummy-broadcast-timers.patch
+x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch
+usb-xhci-fix-bit-definitions-for-iman-register.patch
+usb-xhci-correctly-enable-interrupts.patch
+usb-cdc-acm-fix-device-unregistration.patch
+usb-ehci-fix-regression-during-bus-resume.patch
+usb-ehci-fix-regression-in-qh-unlinking.patch
+usb-gadget-ffs-fix-enable-multiple-instances.patch
+usb-serial-fix-interface-refcounting.patch
+efivars-allow-disabling-use-as-a-pstore-backend.patch
+efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch
+efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch
+acpi-rework-acpi_get_child-to-be-more-efficient.patch
diff --git a/queue-3.8/usb-cdc-acm-fix-device-unregistration.patch b/queue-3.8/usb-cdc-acm-fix-device-unregistration.patch
new file mode 100644 (file)
index 0000000..c2a9f13
--- /dev/null
@@ -0,0 +1,52 @@
+From cb25505fc604292c70fc02143fc102f54c8595f0 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:06 +0100
+Subject: USB: cdc-acm: fix device unregistration
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit cb25505fc604292c70fc02143fc102f54c8595f0 upstream.
+
+Unregister tty device in disconnect as is required by the USB stack.
+
+By deferring unregistration to when the last tty reference is dropped,
+the parent interface device can get unregistered before the child
+resulting in broken hotplug events being generated when the tty is
+finally closed:
+
+KERNEL[2290.798128] remove   /devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:3.1 (usb)
+KERNEL[2290.804589] remove   /devices/pci0000:00/0000:00:1d.7/usb2/2-1 (usb)
+KERNEL[2294.554799] remove   /2-1:3.1/tty/ttyACM0 (tty)
+
+The driver must deal with tty callbacks after disconnect by checking the
+disconnected flag. Specifically, further opens must be prevented and
+this is already implemented.
+
+Acked-by: Oliver Neukum <oneukum@suse.de>
+Cc: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -600,7 +600,6 @@ static void acm_port_destruct(struct tty
+       dev_dbg(&acm->control->dev, "%s\n", __func__);
+-      tty_unregister_device(acm_tty_driver, acm->minor);
+       acm_release_minor(acm);
+       usb_put_intf(acm->control);
+       kfree(acm->country_codes);
+@@ -1418,6 +1417,8 @@ static void acm_disconnect(struct usb_in
+       stop_data_traffic(acm);
++      tty_unregister_device(acm_tty_driver, acm->minor);
++
+       usb_free_urb(acm->ctrlurb);
+       for (i = 0; i < ACM_NW; i++)
+               usb_free_urb(acm->wb[i].urb);
diff --git a/queue-3.8/usb-ehci-fix-regression-during-bus-resume.patch b/queue-3.8/usb-ehci-fix-regression-during-bus-resume.patch
new file mode 100644 (file)
index 0000000..307b818
--- /dev/null
@@ -0,0 +1,85 @@
+From 2a40f324541ee61c22146214349c2ce9f5c30bcf Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 15 Mar 2013 14:40:26 -0400
+Subject: USB: EHCI: fix regression during bus resume
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 2a40f324541ee61c22146214349c2ce9f5c30bcf upstream.
+
+This patch (as1663) fixes a regression caused by commit
+6e0c3339a6f19d748f16091d0a05adeb1e1f822b (USB: EHCI: unlink one async
+QH at a time).  In order to avoid keeping multiple QHs in an unusable
+intermediate state, that commit changed unlink_empty_async() so that
+it unlinks only one empty QH at a time.
+
+However, when the EHCI root hub is suspended, _all_ async QHs need to
+be unlinked.  ehci_bus_suspend() used to do this by calling
+unlink_empty_async(), but now this only unlinks one of the QHs, not
+all of them.
+
+The symptom is that when the root hub is resumed, USB communications
+don't work for some period of time.  This is because ehci-hcd doesn't
+realize it needs to restart the async schedule; it assumes that
+because some QHs are already on the schedule, the schedule must be
+running.
+
+The easiest way to fix the problem is add a new function that unlinks
+all the async QHs when the root hub is suspended.
+
+This patch should be applied to all kernels that have the 6e0c3339a6f1
+commit.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: Adrian Bassett <adrian.bassett@hotmail.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-hcd.c |    1 +
+ drivers/usb/host/ehci-hub.c |    2 +-
+ drivers/usb/host/ehci-q.c   |   13 +++++++++++++
+ 3 files changed, 15 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -302,6 +302,7 @@ static void ehci_quiesce (struct ehci_hc
+ static void end_unlink_async(struct ehci_hcd *ehci);
+ static void unlink_empty_async(struct ehci_hcd *ehci);
++static void unlink_empty_async_suspended(struct ehci_hcd *ehci);
+ static void ehci_work(struct ehci_hcd *ehci);
+ static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
+ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -328,7 +328,7 @@ static int ehci_bus_suspend (struct usb_
+       ehci->rh_state = EHCI_RH_SUSPENDED;
+       end_unlink_async(ehci);
+-      unlink_empty_async(ehci);
++      unlink_empty_async_suspended(ehci);
+       ehci_handle_intr_unlinks(ehci);
+       end_free_itds(ehci);
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -1316,6 +1316,19 @@ static void unlink_empty_async(struct eh
+       }
+ }
++/* The root hub is suspended; unlink all the async QHs */
++static void unlink_empty_async_suspended(struct ehci_hcd *ehci)
++{
++      struct ehci_qh          *qh;
++
++      while (ehci->async->qh_next.qh) {
++              qh = ehci->async->qh_next.qh;
++              WARN_ON(!list_empty(&qh->qtd_list));
++              single_unlink_async(ehci, qh);
++      }
++      start_iaa_cycle(ehci, false);
++}
++
+ /* makes sure the async qh will become idle */
+ /* caller must own ehci->lock */
diff --git a/queue-3.8/usb-ehci-fix-regression-in-qh-unlinking.patch b/queue-3.8/usb-ehci-fix-regression-in-qh-unlinking.patch
new file mode 100644 (file)
index 0000000..77e9e99
--- /dev/null
@@ -0,0 +1,49 @@
+From d714aaf649460cbfd5e82e75520baa856b4fa0a0 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 20 Mar 2013 15:07:26 -0400
+Subject: USB: EHCI: fix regression in QH unlinking
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit d714aaf649460cbfd5e82e75520baa856b4fa0a0 upstream.
+
+This patch (as1670) fixes a regression caused by commit
+6402c796d3b4205d3d7296157956c5100a05d7d6 (USB: EHCI: work around
+silicon bug in Intel's EHCI controllers).  The workaround goes through
+two IAA cycles for each QH being unlinked.  During the first cycle,
+the QH is not added to the async_iaa list (because it isn't fully gone
+from the hardware yet), which means that list will be empty.
+
+Unfortunately, I forgot to update the IAA watchdog timer routine.  It
+thinks that an empty async_iaa list means the timer expiration was an
+error, which isn't true any more.  This problem didn't show up during
+initial testing because the controllers being tested all had working
+IAA interrupts.  But not all controllers do, and when the watchdog
+timer expires, the empty-list check prevents the second IAA cycle from
+starting.  As a result, URB unlinks never complete.  The check needs
+to be removed.
+
+Among the symptoms of the regression are processes stuck in D wait
+states and hangs during system shutdown.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: Stephen Warren <swarren@wwwdotorg.org>
+Reported-and-tested-by: Sven Joachim <svenjoac@gmx.de>
+Reported-by: Andreas Bombe <aeb@debian.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-timer.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ehci-timer.c
++++ b/drivers/usb/host/ehci-timer.c
+@@ -304,7 +304,7 @@ static void ehci_iaa_watchdog(struct ehc
+        * (a) SMP races against real IAA firing and retriggering, and
+        * (b) clean HC shutdown, when IAA watchdog was pending.
+        */
+-      if (ehci->async_iaa) {
++      if (1) {
+               u32 cmd, status;
+               /* If we get here, IAA is *REALLY* late.  It's barely
diff --git a/queue-3.8/usb-gadget-ffs-fix-enable-multiple-instances.patch b/queue-3.8/usb-gadget-ffs-fix-enable-multiple-instances.patch
new file mode 100644 (file)
index 0000000..7cc10c6
--- /dev/null
@@ -0,0 +1,47 @@
+From 3416905ba058e43112ad7b1b4859797f027f5a07 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 11 Mar 2013 16:32:14 +0100
+Subject: usb: gadget: ffs: fix enable multiple instances
+
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+
+commit 3416905ba058e43112ad7b1b4859797f027f5a07 upstream.
+
+This patch fixes an "off-by-one" bug found in
+581791f (FunctionFS: enable multiple functions).
+
+During gfs_bind/gfs_unbind the functionfs_bind/functionfs_unbind should be
+called for every functionfs instance. With the "i" pre-decremented they
+were not called for the zeroth instance.
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+[ balbi@ti.com : added offending commit's subject ]
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/g_ffs.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -357,7 +357,7 @@ static int gfs_bind(struct usb_composite
+               goto error;
+       gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
+-      for (i = func_num; --i; ) {
++      for (i = func_num; i--; ) {
+               ret = functionfs_bind(ffs_tab[i].ffs_data, cdev);
+               if (unlikely(ret < 0)) {
+                       while (++i < func_num)
+@@ -413,7 +413,7 @@ static int gfs_unbind(struct usb_composi
+               gether_cleanup();
+       gfs_ether_setup = false;
+-      for (i = func_num; --i; )
++      for (i = func_num; i--; )
+               if (ffs_tab[i].ffs_data)
+                       functionfs_unbind(ffs_tab[i].ffs_data);
diff --git a/queue-3.8/usb-serial-fix-interface-refcounting.patch b/queue-3.8/usb-serial-fix-interface-refcounting.patch
new file mode 100644 (file)
index 0000000..2b58247
--- /dev/null
@@ -0,0 +1,41 @@
+From d7971051e4df825e0bc11b995e87bfe86355b8e5 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:09 +0100
+Subject: USB: serial: fix interface refcounting
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit d7971051e4df825e0bc11b995e87bfe86355b8e5 upstream.
+
+Make sure the interface is not released before our serial device.
+
+Note that drivers are still not allowed to access the interface in
+any way that may interfere with another driver that may have gotten
+bound to the same interface after disconnect returns.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/usb-serial.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -151,6 +151,7 @@ static void destroy_serial(struct kref *
+               }
+       }
++      usb_put_intf(serial->interface);
+       usb_put_dev(serial->dev);
+       kfree(serial);
+ }
+@@ -614,7 +615,7 @@ static struct usb_serial *create_serial(
+       }
+       serial->dev = usb_get_dev(dev);
+       serial->type = driver;
+-      serial->interface = interface;
++      serial->interface = usb_get_intf(interface);
+       kref_init(&serial->kref);
+       mutex_init(&serial->disc_mutex);
+       serial->minor = SERIAL_TTY_NO_MINOR;
diff --git a/queue-3.8/usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch b/queue-3.8/usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch
new file mode 100644 (file)
index 0000000..6df05ee
--- /dev/null
@@ -0,0 +1,37 @@
+From 29f86e66428ee083aec106cca1748dc63d98ce23 Mon Sep 17 00:00:00 2001
+From: Dmitry Artamonow <mad_soft@inbox.ru>
+Date: Sat, 9 Mar 2013 20:30:58 +0400
+Subject: usb-storage: add unusual_devs entry for Samsung YP-Z3 mp3 player
+
+From: Dmitry Artamonow <mad_soft@inbox.ru>
+
+commit 29f86e66428ee083aec106cca1748dc63d98ce23 upstream.
+
+Device stucks on filesystem writes, unless following quirk is passed:
+  echo 04e8:5136:m > /sys/module/usb_storage/parameters/quirks
+
+Add corresponding entry to unusual_devs.h
+
+Signed-off-by: Dmitry Artamonow <mad_soft@inbox.ru>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/unusual_devs.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -488,6 +488,13 @@ UNUSUAL_DEV(  0x04e8, 0x5122, 0x0000, 0x
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG),
++/* Added by Dmitry Artamonow <mad_soft@inbox.ru> */
++UNUSUAL_DEV(  0x04e8, 0x5136, 0x0000, 0x9999,
++              "Samsung",
++              "YP-Z3",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_MAX_SECTORS_64),
++
+ /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
+  * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
+  * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
diff --git a/queue-3.8/usb-xhci-correctly-enable-interrupts.patch b/queue-3.8/usb-xhci-correctly-enable-interrupts.patch
new file mode 100644 (file)
index 0000000..2890f60
--- /dev/null
@@ -0,0 +1,99 @@
+From 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Mon, 4 Mar 2013 17:14:43 +0100
+Subject: USB: xhci: correctly enable interrupts
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb upstream.
+
+xhci has its own interrupt enabling routine, which will try to
+use MSI-X/MSI if present. So the usb core shouldn't try to enable
+legacy interrupts; on some machines the xhci legacy IRQ setting
+is invalid.
+
+v3: Be careful to not break XHCI_BROKEN_MSI workaround (by trenn)
+
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Oliver Neukum <oneukum@suse.de>
+Cc: Thomas Renninger <trenn@suse.de>
+Cc: Yinghai Lu <yinghai@kernel.org>
+Cc: Frederik Himpe <fhimpe@vub.ac.be>
+Cc: David Haerdeman <david@hardeman.nu>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Acked-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Reviewed-by: Thomas Renninger <trenn@suse.de>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hcd-pci.c |   23 ++++++++++++++---------
+ drivers/usb/host/xhci.c    |    3 ++-
+ 2 files changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/core/hcd-pci.c
++++ b/drivers/usb/core/hcd-pci.c
+@@ -173,6 +173,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
+       struct hc_driver        *driver;
+       struct usb_hcd          *hcd;
+       int                     retval;
++      int                     hcd_irq = 0;
+       if (usb_disabled())
+               return -ENODEV;
+@@ -187,15 +188,19 @@ int usb_hcd_pci_probe(struct pci_dev *de
+               return -ENODEV;
+       dev->current_state = PCI_D0;
+-      /* The xHCI driver supports MSI and MSI-X,
+-       * so don't fail if the BIOS doesn't provide a legacy IRQ.
++      /*
++       * The xHCI driver has its own irq management
++       * make sure irq setup is not touched for xhci in generic hcd code
+        */
+-      if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
+-              dev_err(&dev->dev,
+-                      "Found HC with no IRQ.  Check BIOS/PCI %s setup!\n",
+-                      pci_name(dev));
+-              retval = -ENODEV;
+-              goto disable_pci;
++      if ((driver->flags & HCD_MASK) != HCD_USB3) {
++              if (!dev->irq) {
++                      dev_err(&dev->dev,
++                      "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
++                              pci_name(dev));
++                      retval = -ENODEV;
++                      goto disable_pci;
++              }
++              hcd_irq = dev->irq;
+       }
+       hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
+@@ -245,7 +250,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
+       pci_set_master(dev);
+-      retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
++      retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
+       if (retval != 0)
+               goto unmap_registers;
+       set_hs_companion(dev, hcd);
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -350,7 +350,7 @@ static int xhci_try_enable_msi(struct us
+        * generate interrupts.  Don't even try to enable MSI.
+        */
+       if (xhci->quirks & XHCI_BROKEN_MSI)
+-              return 0;
++              goto legacy_irq;
+       /* unregister the legacy interrupt */
+       if (hcd->irq)
+@@ -371,6 +371,7 @@ static int xhci_try_enable_msi(struct us
+               return -EINVAL;
+       }
++ legacy_irq:
+       /* fall back to legacy interrupt*/
+       ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
+                       hcd->irq_descr, hcd);
diff --git a/queue-3.8/usb-xhci-fix-bit-definitions-for-iman-register.patch b/queue-3.8/usb-xhci-fix-bit-definitions-for-iman-register.patch
new file mode 100644 (file)
index 0000000..1257725
--- /dev/null
@@ -0,0 +1,42 @@
+From f8264340e694604863255cc0276491d17c402390 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dtor@vmware.com>
+Date: Mon, 25 Feb 2013 10:56:01 -0800
+Subject: USB: xhci - fix bit definitions for IMAN register
+
+From: Dmitry Torokhov <dtor@vmware.com>
+
+commit f8264340e694604863255cc0276491d17c402390 upstream.
+
+According to XHCI specification (5.5.2.1) the IP is bit 0 and IE is bit 1
+of IMAN register. Previously their definitions were reversed.
+
+Even though there are no ill effects being observed from the swapped
+definitions (because IMAN_IP is RW1C and in legacy PCI case we come in
+with it already set to 1 so it was clearing itself even though we were
+setting IMAN_IE instead of IMAN_IP), we should still correct the values.
+
+This patch should be backported to kernels as old as 2.6.36, that
+contain the commit 4e833c0b87a30798e67f06120cecebef6ee9644c "xhci: don't
+re-enable IE constantly".
+
+Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.h |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -206,8 +206,8 @@ struct xhci_op_regs {
+ /* bits 12:31 are reserved (and should be preserved on writes). */
+ /* IMAN - Interrupt Management Register */
+-#define IMAN_IP               (1 << 1)
+-#define IMAN_IE               (1 << 0)
++#define IMAN_IE               (1 << 1)
++#define IMAN_IP               (1 << 0)
+ /* USBSTS - USB status - status bitmasks */
+ /* HC not running - set to 1 when run/stop bit is cleared. */
diff --git a/queue-3.8/watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch b/queue-3.8/watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch
new file mode 100644 (file)
index 0000000..9f4186d
--- /dev/null
@@ -0,0 +1,248 @@
+From 18e4321276fcf083b85b788fee7cf15be29ed72a Mon Sep 17 00:00:00 2001
+From: Takahisa Tanaka <mc74hc00@gmail.com>
+Date: Sun, 3 Mar 2013 14:52:07 +0900
+Subject: watchdog: sp5100_tco: Remove code that may cause a boot failure
+
+From: Takahisa Tanaka <mc74hc00@gmail.com>
+
+commit 18e4321276fcf083b85b788fee7cf15be29ed72a upstream.
+
+A problem was found on PC's with the SB700 chipset: The PC fails to
+load BIOS after running the 3.8.x kernel until the power is completely
+cut off. It occurs in all 3.8.x versions and the mainline version as of
+2/4. The issue does not occur with the 3.7.x builds.
+
+There are two methods for accessing the watchdog registers.
+
+ 1. Re-programming a resource address obtained by allocate_resource()
+to chipset.
+ 2. Use the direct memory-mapped IO access.
+
+The method 1 can be used by all the chipsets (SP5100, SB7x0, SB8x0 or
+later). However, experience shows that only PC with the SB8x0 (or
+later) chipsets can use the method 2.
+
+This patch removes the method 1, because the critical problem was found.
+That's why the watchdog timer was able to be used on SP5100 and SB7x0
+chipsets until now.
+
+Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1116835
+Link: https://lkml.org/lkml/2013/2/14/271
+
+Signed-off-by: Takahisa Tanaka <mc74hc00@gmail.com>
+Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/watchdog/sp5100_tco.c |  126 ++----------------------------------------
+ 1 file changed, 6 insertions(+), 120 deletions(-)
+
+--- a/drivers/watchdog/sp5100_tco.c
++++ b/drivers/watchdog/sp5100_tco.c
+@@ -40,13 +40,12 @@
+ #include "sp5100_tco.h"
+ /* Module and version information */
+-#define TCO_VERSION "0.03"
++#define TCO_VERSION "0.05"
+ #define TCO_MODULE_NAME "SP5100 TCO timer"
+ #define TCO_DRIVER_NAME   TCO_MODULE_NAME ", v" TCO_VERSION
+ /* internal variables */
+ static u32 tcobase_phys;
+-static u32 resbase_phys;
+ static u32 tco_wdt_fired;
+ static void __iomem *tcobase;
+ static unsigned int pm_iobase;
+@@ -54,10 +53,6 @@ static DEFINE_SPINLOCK(tco_lock);   /* Gua
+ static unsigned long timer_alive;
+ static char tco_expect_close;
+ static struct pci_dev *sp5100_tco_pci;
+-static struct resource wdt_res = {
+-      .name = "Watchdog Timer",
+-      .flags = IORESOURCE_MEM,
+-};
+ /* the watchdog platform device */
+ static struct platform_device *sp5100_tco_platform_device;
+@@ -75,12 +70,6 @@ module_param(nowayout, bool, 0);
+ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started."
+               " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+-static unsigned int force_addr;
+-module_param(force_addr, uint, 0);
+-MODULE_PARM_DESC(force_addr, "Force the use of specified MMIO address."
+-              " ONLY USE THIS PARAMETER IF YOU REALLY KNOW"
+-              " WHAT YOU ARE DOING (default=none)");
+-
+ /*
+  * Some TCO specific functions
+  */
+@@ -176,39 +165,6 @@ static void tco_timer_enable(void)
+       }
+ }
+-static void tco_timer_disable(void)
+-{
+-      int val;
+-
+-      if (sp5100_tco_pci->revision >= 0x40) {
+-              /* For SB800 or later */
+-              /* Enable watchdog decode bit and Disable watchdog timer */
+-              outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG);
+-              val = inb(SB800_IO_PM_DATA_REG);
+-              val |= SB800_PCI_WATCHDOG_DECODE_EN;
+-              val |= SB800_PM_WATCHDOG_DISABLE;
+-              outb(val, SB800_IO_PM_DATA_REG);
+-      } else {
+-              /* For SP5100 or SB7x0 */
+-              /* Enable watchdog decode bit */
+-              pci_read_config_dword(sp5100_tco_pci,
+-                                    SP5100_PCI_WATCHDOG_MISC_REG,
+-                                    &val);
+-
+-              val |= SP5100_PCI_WATCHDOG_DECODE_EN;
+-
+-              pci_write_config_dword(sp5100_tco_pci,
+-                                     SP5100_PCI_WATCHDOG_MISC_REG,
+-                                     val);
+-
+-              /* Disable Watchdog timer */
+-              outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG);
+-              val = inb(SP5100_IO_PM_DATA_REG);
+-              val |= SP5100_PM_WATCHDOG_DISABLE;
+-              outb(val, SP5100_IO_PM_DATA_REG);
+-      }
+-}
+-
+ /*
+  *    /dev/watchdog handling
+  */
+@@ -361,7 +317,7 @@ static unsigned char sp5100_tco_setupdev
+ {
+       struct pci_dev *dev = NULL;
+       const char *dev_name = NULL;
+-      u32 val, tmp_val;
++      u32 val;
+       u32 index_reg, data_reg, base_addr;
+       /* Match the PCI device */
+@@ -459,63 +415,8 @@ static unsigned char sp5100_tco_setupdev
+       } else
+               pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val);
+-      /*
+-       * Lastly re-programming the watchdog timer MMIO address,
+-       * This method is a last resort...
+-       *
+-       * Before re-programming, to ensure that the watchdog timer
+-       * is disabled, disable the watchdog timer.
+-       */
+-      tco_timer_disable();
+-
+-      if (force_addr) {
+-              /*
+-               * Force the use of watchdog timer MMIO address, and aligned to
+-               * 8byte boundary.
+-               */
+-              force_addr &= ~0x7;
+-              val = force_addr;
+-
+-              pr_info("Force the use of 0x%04x as MMIO address\n", val);
+-      } else {
+-              /*
+-               * Get empty slot into the resource tree for watchdog timer.
+-               */
+-              if (allocate_resource(&iomem_resource,
+-                                    &wdt_res,
+-                                    SP5100_WDT_MEM_MAP_SIZE,
+-                                    0xf0000000,
+-                                    0xfffffff8,
+-                                    0x8,
+-                                    NULL,
+-                                    NULL)) {
+-                      pr_err("MMIO allocation failed\n");
+-                      goto unreg_region;
+-              }
+-
+-              val = resbase_phys = wdt_res.start;
+-              pr_debug("Got 0x%04x from resource tree\n", val);
+-      }
+-
+-      /* Restore to the low three bits */
+-      outb(base_addr+0, index_reg);
+-      tmp_val = val | (inb(data_reg) & 0x7);
+-
+-      /* Re-programming the watchdog timer base address */
+-      outb(base_addr+0, index_reg);
+-      outb((tmp_val >>  0) & 0xff, data_reg);
+-      outb(base_addr+1, index_reg);
+-      outb((tmp_val >>  8) & 0xff, data_reg);
+-      outb(base_addr+2, index_reg);
+-      outb((tmp_val >> 16) & 0xff, data_reg);
+-      outb(base_addr+3, index_reg);
+-      outb((tmp_val >> 24) & 0xff, data_reg);
+-
+-      if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
+-                                                                 dev_name)) {
+-              pr_err("MMIO address 0x%04x already in use\n", val);
+-              goto unreg_resource;
+-      }
++      pr_notice("failed to find MMIO address, giving up.\n");
++      goto  unreg_region;
+ setup_wdt:
+       tcobase_phys = val;
+@@ -555,9 +456,6 @@ setup_wdt:
+ unreg_mem_region:
+       release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+-unreg_resource:
+-      if (resbase_phys)
+-              release_resource(&wdt_res);
+ unreg_region:
+       release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
+ exit:
+@@ -567,7 +465,6 @@ exit:
+ static int sp5100_tco_init(struct platform_device *dev)
+ {
+       int ret;
+-      char addr_str[16];
+       /*
+        * Check whether or not the hardware watchdog is there. If found, then
+@@ -599,23 +496,14 @@ static int sp5100_tco_init(struct platfo
+       clear_bit(0, &timer_alive);
+       /* Show module parameters */
+-      if (force_addr == tcobase_phys)
+-              /* The force_addr is vaild */
+-              sprintf(addr_str, "0x%04x", force_addr);
+-      else
+-              strcpy(addr_str, "none");
+-
+-      pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d, "
+-              "force_addr=%s)\n",
+-              tcobase, heartbeat, nowayout, addr_str);
++      pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
++              tcobase, heartbeat, nowayout);
+       return 0;
+ exit:
+       iounmap(tcobase);
+       release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+-      if (resbase_phys)
+-              release_resource(&wdt_res);
+       release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
+       return ret;
+ }
+@@ -630,8 +518,6 @@ static void sp5100_tco_cleanup(void)
+       misc_deregister(&sp5100_tco_miscdev);
+       iounmap(tcobase);
+       release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+-      if (resbase_phys)
+-              release_resource(&wdt_res);
+       release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
+ }
diff --git a/queue-3.8/watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch b/queue-3.8/watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch
new file mode 100644 (file)
index 0000000..00cb487
--- /dev/null
@@ -0,0 +1,51 @@
+From 81fc933f176cd95f757bfc8a98109ef422598b79 Mon Sep 17 00:00:00 2001
+From: Takahisa Tanaka <mc74hc00@gmail.com>
+Date: Sun, 3 Mar 2013 14:48:00 +0900
+Subject: watchdog: sp5100_tco: Set the AcpiMmioSel bitmask value to 1 instead of 2
+
+From: Takahisa Tanaka <mc74hc00@gmail.com>
+
+commit 81fc933f176cd95f757bfc8a98109ef422598b79 upstream.
+
+The AcpiMmioSel bit is bit 1 in the AcpiMmioEn register, but the current
+sp5100_tco driver is using bit 2.
+
+See 2.3.3 Power Management (PM) Registers page 150 of the
+AMD SB800-Series Southbridges Register Reference Guide [1].
+
+        AcpiMmioEn - RW – 8/16/32 bits - [PM_Reg: 24h]
+        Field Name        Bits  Default  Description
+        AcpiMMioDecodeEn  0     0b       Set to 1 to enable AcpiMMio space.
+        AcpiMMIoSel       1     0b       Set AcpiMMio registers to be memory-mapped or IO-mapped space.
+                                         0: Memory-mapped space
+                                         1: I/O-mapped space
+
+The sp5100_tco driver expects zero as a value of AcpiMmioSel (bit 1).
+
+Fortunately, no problems were caused by this typo, because the default
+value of the undocumented misused bit 2 seems to be zero.
+
+However, the sp5100_tco driver should use the correct bitmask value.
+
+[1] http://support.amd.com/us/Embedded_TechDocs/45482.pdf
+
+Signed-off-by: Takahisa Tanaka <mc74hc00@gmail.com>
+Signed-off-by: Paul Menzel <paulepanter@users.sourceforge.net>
+Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/watchdog/sp5100_tco.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/watchdog/sp5100_tco.h
++++ b/drivers/watchdog/sp5100_tco.h
+@@ -57,7 +57,7 @@
+ #define SB800_PM_WATCHDOG_DISABLE     (1 << 2)
+ #define SB800_PM_WATCHDOG_SECOND_RES  (3 << 0)
+ #define SB800_ACPI_MMIO_DECODE_EN     (1 << 0)
+-#define SB800_ACPI_MMIO_SEL           (1 << 2)
++#define SB800_ACPI_MMIO_SEL           (1 << 1)
+ #define SB800_PM_WDT_MMIO_OFFSET      0xB00
diff --git a/queue-3.8/x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch b/queue-3.8/x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch
new file mode 100644 (file)
index 0000000..4d1add3
--- /dev/null
@@ -0,0 +1,40 @@
+From 66db3feb486c01349f767b98ebb10b0c3d2d021b Mon Sep 17 00:00:00 2001
+From: CQ Tang <cq.tang@intel.com>
+Date: Mon, 18 Mar 2013 11:02:21 -0400
+Subject: x86-64: Fix the failure case in copy_user_handle_tail()
+
+From: CQ Tang <cq.tang@intel.com>
+
+commit 66db3feb486c01349f767b98ebb10b0c3d2d021b upstream.
+
+The increment of "to" in copy_user_handle_tail() will have incremented
+before a failure has been noted.  This causes us to skip a byte in the
+failure case.
+
+Only do the increment when assured there is no failure.
+
+Signed-off-by: CQ Tang <cq.tang@intel.com>
+Link: http://lkml.kernel.org/r/20130318150221.8439.993.stgit@phlsvslse11.ph.intel.com
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/lib/usercopy_64.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/lib/usercopy_64.c
++++ b/arch/x86/lib/usercopy_64.c
+@@ -74,10 +74,10 @@ copy_user_handle_tail(char *to, char *fr
+       char c;
+       unsigned zero_len;
+-      for (; len; --len) {
++      for (; len; --len, to++) {
+               if (__get_user_nocheck(c, from++, sizeof(char)))
+                       break;
+-              if (__put_user_nocheck(c, to++, sizeof(char)))
++              if (__put_user_nocheck(c, to, sizeof(char)))
+                       break;
+       }