]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Nov 2012 23:30:52 +0000 (15:30 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Nov 2012 23:30:52 +0000 (15:30 -0800)
added patches:
crypto-cryptd-disable-softirqs-in-cryptd_queue_worker-to-prevent-data-corruption.patch
fanotify-fix-missing-break.patch
pci-pm-fix-deadlock-when-unbinding-device-if-parent-in-d3cold.patch

queue-3.0/crypto-cryptd-disable-softirqs-in-cryptd_queue_worker-to-prevent-data-corruption.patch [new file with mode: 0644]
queue-3.0/fanotify-fix-missing-break.patch [new file with mode: 0644]
queue-3.0/pci-pm-fix-deadlock-when-unbinding-device-if-parent-in-d3cold.patch [new file with mode: 0644]
queue-3.0/series

diff --git a/queue-3.0/crypto-cryptd-disable-softirqs-in-cryptd_queue_worker-to-prevent-data-corruption.patch b/queue-3.0/crypto-cryptd-disable-softirqs-in-cryptd_queue_worker-to-prevent-data-corruption.patch
new file mode 100644 (file)
index 0000000..8151a7a
--- /dev/null
@@ -0,0 +1,53 @@
+From 9efade1b3e981f5064f9db9ca971b4dc7557ae42 Mon Sep 17 00:00:00 2001
+From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+Date: Sun, 21 Oct 2012 20:42:28 +0300
+Subject: crypto: cryptd - disable softirqs in cryptd_queue_worker to prevent data corruption
+
+From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+commit 9efade1b3e981f5064f9db9ca971b4dc7557ae42 upstream.
+
+cryptd_queue_worker attempts to prevent simultaneous accesses to crypto
+workqueue by cryptd_enqueue_request using preempt_disable/preempt_enable.
+However cryptd_enqueue_request might be called from softirq context,
+so add local_bh_disable/local_bh_enable to prevent data corruption and
+panics.
+
+Bug report at http://marc.info/?l=linux-crypto-vger&m=134858649616319&w=2
+
+v2:
+ - Disable software interrupts instead of hardware interrupts
+
+Reported-by: Gurucharan Shetty <gurucharan.shetty@gmail.com>
+Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/cryptd.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct w
+       struct crypto_async_request *req, *backlog;
+       cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
+-      /* Only handle one request at a time to avoid hogging crypto
+-       * workqueue. preempt_disable/enable is used to prevent
+-       * being preempted by cryptd_enqueue_request() */
++      /*
++       * Only handle one request at a time to avoid hogging crypto workqueue.
++       * preempt_disable/enable is used to prevent being preempted by
++       * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
++       * cryptd_enqueue_request() being accessed from software interrupts.
++       */
++      local_bh_disable();
+       preempt_disable();
+       backlog = crypto_get_backlog(&cpu_queue->queue);
+       req = crypto_dequeue_request(&cpu_queue->queue);
+       preempt_enable();
++      local_bh_enable();
+       if (!req)
+               return;
diff --git a/queue-3.0/fanotify-fix-missing-break.patch b/queue-3.0/fanotify-fix-missing-break.patch
new file mode 100644 (file)
index 0000000..ff57c42
--- /dev/null
@@ -0,0 +1,41 @@
+From 848561d368751a1c0f679b9f045a02944506a801 Mon Sep 17 00:00:00 2001
+From: Eric Paris <eparis@redhat.com>
+Date: Thu, 8 Nov 2012 15:53:37 -0800
+Subject: fanotify: fix missing break
+
+From: Eric Paris <eparis@redhat.com>
+
+commit 848561d368751a1c0f679b9f045a02944506a801 upstream.
+
+Anders Blomdell noted in 2010 that Fanotify lost events and provided a
+test case.  Eric Paris confirmed it was a bug and posted a fix to the
+list
+
+  https://groups.google.com/forum/?fromgroups=#!topic/linux.kernel/RrJfTfyW2BE
+
+but never applied it.  Repeated attempts over time to actually get him
+to apply it have never had a reply from anyone who has raised it
+
+So apply it anyway
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Reported-by: Anders Blomdell <anders.blomdell@control.lth.se>
+Cc: Eric Paris <eparis@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/notify/fanotify/fanotify.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify
+                       if ((old->path.mnt == new->path.mnt) &&
+                           (old->path.dentry == new->path.dentry))
+                               return true;
++                      break;
+               case (FSNOTIFY_EVENT_NONE):
+                       return true;
+               default:
diff --git a/queue-3.0/pci-pm-fix-deadlock-when-unbinding-device-if-parent-in-d3cold.patch b/queue-3.0/pci-pm-fix-deadlock-when-unbinding-device-if-parent-in-d3cold.patch
new file mode 100644 (file)
index 0000000..af83b89
--- /dev/null
@@ -0,0 +1,156 @@
+From 90b5c1d7c45eeb622302680ff96ed30c1a2b6f0e Mon Sep 17 00:00:00 2001
+From: Huang Ying <ying.huang@intel.com>
+Date: Wed, 24 Oct 2012 14:54:13 +0800
+Subject: PCI/PM: Fix deadlock when unbinding device if parent in D3cold
+
+From: Huang Ying <ying.huang@intel.com>
+
+commit 90b5c1d7c45eeb622302680ff96ed30c1a2b6f0e upstream.
+
+If a PCI device and its parents are put into D3cold, unbinding the
+device will trigger deadlock as follow:
+
+- driver_unbind
+  - device_release_driver
+    - device_lock(dev)                         <--- previous lock here
+    - __device_release_driver
+      - pm_runtime_get_sync
+        ...
+          - rpm_resume(dev)
+            - rpm_resume(dev->parent)
+              ...
+                - pci_pm_runtime_resume
+                  ...
+                  - pci_set_power_state
+                    - __pci_start_power_transition
+                      - pci_wakeup_bus(dev->parent->subordinate)
+                        - pci_walk_bus
+                          - device_lock(dev)   <--- deadlock here
+
+
+If we do not do device_lock in pci_walk_bus, we can avoid deadlock.
+Device_lock in pci_walk_bus is introduced in commit:
+d71374dafbba7ec3f67371d3b7e9f6310a588808, corresponding email thread
+is: https://lkml.org/lkml/2006/5/26/38.  The patch author Zhang Yanmin
+said device_lock is added to pci_walk_bus because:
+
+  Some error handling functions call pci_walk_bus. For example, PCIe
+  aer. Here we lock the device, so the driver wouldn't detach from the
+  device, as the cb might call driver's callback function.
+
+So I fixed the deadlock as follows:
+
+- remove device_lock from pci_walk_bus
+- add device_lock into callback if callback will call driver's callback
+
+I checked pci_walk_bus users one by one, and found only PCIe aer needs
+device lock.
+
+Signed-off-by: Huang Ying <ying.huang@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+CC: Zhang Yanmin <yanmin.zhang@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/bus.c                  |    3 ---
+ drivers/pci/pcie/aer/aerdrv_core.c |   20 ++++++++++++++++----
+ 2 files changed, 16 insertions(+), 7 deletions(-)
+
+--- a/drivers/pci/bus.c
++++ b/drivers/pci/bus.c
+@@ -284,10 +284,7 @@ void pci_walk_bus(struct pci_bus *top, i
+               } else
+                       next = dev->bus_list.next;
+-              /* Run device routines with the device locked */
+-              device_lock(&dev->dev);
+               retval = cb(dev, userdata);
+-              device_unlock(&dev->dev);
+               if (retval)
+                       break;
+       }
+--- a/drivers/pci/pcie/aer/aerdrv_core.c
++++ b/drivers/pci/pcie/aer/aerdrv_core.c
+@@ -243,6 +243,7 @@ static int report_error_detected(struct
+       struct aer_broadcast_data *result_data;
+       result_data = (struct aer_broadcast_data *) data;
++      device_lock(&dev->dev);
+       dev->error_state = result_data->state;
+       if (!dev->driver ||
+@@ -261,12 +262,14 @@ static int report_error_detected(struct
+                                  dev->driver ?
+                                  "no AER-aware driver" : "no driver");
+               }
+-              return 0;
++              goto out;
+       }
+       err_handler = dev->driver->err_handler;
+       vote = err_handler->error_detected(dev, result_data->state);
+       result_data->result = merge_result(result_data->result, vote);
++out:
++      device_unlock(&dev->dev);
+       return 0;
+ }
+@@ -277,14 +280,17 @@ static int report_mmio_enabled(struct pc
+       struct aer_broadcast_data *result_data;
+       result_data = (struct aer_broadcast_data *) data;
++      device_lock(&dev->dev);
+       if (!dev->driver ||
+               !dev->driver->err_handler ||
+               !dev->driver->err_handler->mmio_enabled)
+-              return 0;
++              goto out;
+       err_handler = dev->driver->err_handler;
+       vote = err_handler->mmio_enabled(dev);
+       result_data->result = merge_result(result_data->result, vote);
++out:
++      device_unlock(&dev->dev);
+       return 0;
+ }
+@@ -295,14 +301,17 @@ static int report_slot_reset(struct pci_
+       struct aer_broadcast_data *result_data;
+       result_data = (struct aer_broadcast_data *) data;
++      device_lock(&dev->dev);
+       if (!dev->driver ||
+               !dev->driver->err_handler ||
+               !dev->driver->err_handler->slot_reset)
+-              return 0;
++              goto out;
+       err_handler = dev->driver->err_handler;
+       vote = err_handler->slot_reset(dev);
+       result_data->result = merge_result(result_data->result, vote);
++out:
++      device_unlock(&dev->dev);
+       return 0;
+ }
+@@ -310,15 +319,18 @@ static int report_resume(struct pci_dev
+ {
+       struct pci_error_handlers *err_handler;
++      device_lock(&dev->dev);
+       dev->error_state = pci_channel_io_normal;
+       if (!dev->driver ||
+               !dev->driver->err_handler ||
+               !dev->driver->err_handler->resume)
+-              return 0;
++              goto out;
+       err_handler = dev->driver->err_handler;
+       err_handler->resume(dev);
++out:
++      device_unlock(&dev->dev);
+       return 0;
+ }
index 32b3a24649be51e9752e5bf205b33be4408a239f..907518dccf6e5eb04f74eb49efa20c80f8471b11 100644 (file)
@@ -1 +1,4 @@
 mm-bugfix-set-current-reclaim_state-to-null-while-returning-from-kswapd.patch
+pci-pm-fix-deadlock-when-unbinding-device-if-parent-in-d3cold.patch
+fanotify-fix-missing-break.patch
+crypto-cryptd-disable-softirqs-in-cryptd_queue_worker-to-prevent-data-corruption.patch