]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 May 2016 21:17:19 +0000 (14:17 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 May 2016 21:17:19 +0000 (14:17 -0700)
added patches:
drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hypervisors.patch
include-linux-poison.h-fix-list_poison-1-2-offset.patch
serial-sh-sci-remove-cpufreq-notifier-to-fix-crash-deadlock.patch

queue-3.14/drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hypervisors.patch [new file with mode: 0644]
queue-3.14/include-linux-poison.h-fix-list_poison-1-2-offset.patch [new file with mode: 0644]
queue-3.14/serial-sh-sci-remove-cpufreq-notifier-to-fix-crash-deadlock.patch [new file with mode: 0644]
queue-3.14/series

diff --git a/queue-3.14/drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hypervisors.patch b/queue-3.14/drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hypervisors.patch
new file mode 100644 (file)
index 0000000..c39d946
--- /dev/null
@@ -0,0 +1,97 @@
+From e513229b4c386e6c9f66298c13fde92f73e6e1ac Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Feb 2015 11:25:51 -0800
+Subject: Drivers: hv: vmbus: prevent cpu offlining on newer hypervisors
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit e513229b4c386e6c9f66298c13fde92f73e6e1ac upstream.
+
+When an SMP Hyper-V guest is running on top of 2012R2 Server and secondary
+cpus are sent offline (with echo 0 > /sys/devices/system/cpu/cpu$cpu/online)
+the system freeze is observed. This happens due to the fact that on newer
+hypervisors (Win8, WS2012R2, ...) vmbus channel handlers are distributed
+across all cpus (see init_vp_index() function in drivers/hv/channel_mgmt.c)
+and on cpu offlining nobody reassigns them to CPU0. Prevent cpu offlining
+when vmbus is loaded until the issue is fixed host-side.
+
+This patch also disables hibernation but it is OK as it is also broken (MCE
+error is hit on resume). Suspend still works.
+
+Tested with WS2008R2 and WS2012R2.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+[ 3chas3@gmail.com: rebase to 3.14-stable ]
+Signed-off-by: Chas Williams <3chas3@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hv/vmbus_drv.c |   36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -31,6 +31,7 @@
+ #include <linux/slab.h>
+ #include <linux/acpi.h>
+ #include <linux/completion.h>
++#include <linux/cpu.h>
+ #include <linux/hyperv.h>
+ #include <linux/kernel_stat.h>
+ #include <asm/hyperv.h>
+@@ -689,6 +690,39 @@ static void vmbus_flow_handler(unsigned
+       desc->action->handler(irq, desc->action->dev_id);
+ }
++#ifdef CONFIG_HOTPLUG_CPU
++static int hyperv_cpu_disable(void)
++{
++      return -ENOSYS;
++}
++
++static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
++{
++      static void *previous_cpu_disable;
++
++      /*
++       * Offlining a CPU when running on newer hypervisors (WS2012R2, Win8,
++       * ...) is not supported at this moment as channel interrupts are
++       * distributed across all of them.
++       */
++
++      if ((vmbus_proto_version == VERSION_WS2008) ||
++          (vmbus_proto_version == VERSION_WIN7))
++              return;
++
++      if (vmbus_loaded) {
++              previous_cpu_disable = smp_ops.cpu_disable;
++              smp_ops.cpu_disable = hyperv_cpu_disable;
++              pr_notice("CPU offlining is not supported by hypervisor\n");
++      } else if (previous_cpu_disable)
++              smp_ops.cpu_disable = previous_cpu_disable;
++}
++#else
++static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
++{
++}
++#endif
++
+ /*
+  * vmbus_bus_init -Main vmbus driver initialization routine.
+  *
+@@ -747,6 +781,7 @@ static int vmbus_bus_init(int irq)
+       if (ret)
+               goto err_alloc;
++      hv_cpu_hotplug_quirk(true);
+       vmbus_request_offers();
+       return 0;
+@@ -984,6 +1019,7 @@ static void __exit vmbus_exit(void)
+       bus_unregister(&hv_bus);
+       hv_cleanup();
+       acpi_bus_unregister_driver(&vmbus_acpi_driver);
++      hv_cpu_hotplug_quirk(false);
+ }
diff --git a/queue-3.14/include-linux-poison.h-fix-list_poison-1-2-offset.patch b/queue-3.14/include-linux-poison.h-fix-list_poison-1-2-offset.patch
new file mode 100644 (file)
index 0000000..dbf43a5
--- /dev/null
@@ -0,0 +1,49 @@
+From 8a5e5e02fc83aaf67053ab53b359af08c6c49aaf Mon Sep 17 00:00:00 2001
+From: Vasily Kulikov <segoon@openwall.com>
+Date: Wed, 9 Sep 2015 15:36:00 -0700
+Subject: include/linux/poison.h: fix LIST_POISON{1,2} offset
+
+From: Vasily Kulikov <segoon@openwall.com>
+
+commit 8a5e5e02fc83aaf67053ab53b359af08c6c49aaf upstream.
+
+Poison pointer values should be small enough to find a room in
+non-mmap'able/hardly-mmap'able space.  E.g.  on x86 "poison pointer space"
+is located starting from 0x0.  Given unprivileged users cannot mmap
+anything below mmap_min_addr, it should be safe to use poison pointers
+lower than mmap_min_addr.
+
+The current poison pointer values of LIST_POISON{1,2} might be too big for
+mmap_min_addr values equal or less than 1 MB (common case, e.g.  Ubuntu
+uses only 0x10000).  There is little point to use such a big value given
+the "poison pointer space" below 1 MB is not yet exhausted.  Changing it
+to a smaller value solves the problem for small mmap_min_addr setups.
+
+The values are suggested by Solar Designer:
+http://www.openwall.com/lists/oss-security/2015/05/02/6
+
+Signed-off-by: Vasily Kulikov <segoon@openwall.com>
+Cc: Solar Designer <solar@openwall.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.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>
+
+---
+ include/linux/poison.h |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/include/linux/poison.h
++++ b/include/linux/poison.h
+@@ -19,8 +19,8 @@
+  * under normal circumstances, used to verify that nobody uses
+  * non-initialized list entries.
+  */
+-#define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)
+-#define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)
++#define LIST_POISON1  ((void *) 0x100 + POISON_POINTER_DELTA)
++#define LIST_POISON2  ((void *) 0x200 + POISON_POINTER_DELTA)
+ /********** include/linux/timer.h **********/
+ /*
diff --git a/queue-3.14/serial-sh-sci-remove-cpufreq-notifier-to-fix-crash-deadlock.patch b/queue-3.14/serial-sh-sci-remove-cpufreq-notifier-to-fix-crash-deadlock.patch
new file mode 100644 (file)
index 0000000..42f4ffe
--- /dev/null
@@ -0,0 +1,124 @@
+From ff1cab374ad98f4b9f408525ca9c08992b4ed784 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Tue, 5 Jan 2016 19:36:37 +0100
+Subject: serial: sh-sci: Remove cpufreq notifier to fix crash/deadlock
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+commit ff1cab374ad98f4b9f408525ca9c08992b4ed784 upstream.
+
+The BSP team noticed that there is spin/mutex lock issue on sh-sci when
+CPUFREQ is used.  The issue is that the notifier function may call
+mutex_lock() while the spinlock is held, which can lead to a BUG().
+This may happen if CPUFREQ is changed while another CPU calls
+clk_get_rate().
+
+Taking the spinlock was added to the notifier function in commit
+e552de2413edad1a ("sh-sci: add platform device private data"), to
+protect the list of serial ports against modification during traversal.
+At that time the Common Clock Framework didn't exist yet, and
+clk_get_rate() just returned clk->rate without taking a mutex.
+Note that since commit d535a2305facf9b4 ("serial: sh-sci: Require a
+device per port mapping."), there's no longer a list of serial ports to
+traverse, and taking the spinlock became superfluous.
+
+To fix the issue, just remove the cpufreq notifier:
+  1. The notifier doesn't work correctly: all it does is update stored
+     clock rates; it does not update the divider in the hardware.
+     The divider will only be updated when calling sci_set_termios().
+     I believe this was broken back in 2004, when the old
+     drivers/char/sh-sci.c driver (where the notifier did update the
+     divider) was replaced by drivers/serial/sh-sci.c (where the
+     notifier just updated port->uartclk).
+     Cfr. full-history-linux commits 6f8deaef2e9675d9 ("[PATCH] sh: port
+     sh-sci driver to the new API") and 3f73fe878dc9210a ("[PATCH]
+     Remove old sh-sci driver").
+  2. On modern SoCs, the sh-sci parent clock rate is no longer related
+     to the CPU clock rate anyway, so using a cpufreq notifier is
+     futile.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+
+---
+ drivers/tty/serial/sh-sci.c |   39 ---------------------------------------
+ 1 file changed, 39 deletions(-)
+
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -38,7 +38,6 @@
+ #include <linux/major.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+-#include <linux/notifier.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+@@ -118,8 +117,6 @@ struct sci_port {
+       struct timer_list               rx_timer;
+       unsigned int                    rx_timeout;
+ #endif
+-
+-      struct notifier_block           freq_transition;
+ };
+ /* Function prototypes */
+@@ -1029,30 +1026,6 @@ static irqreturn_t sci_mpxed_interrupt(i
+       return ret;
+ }
+-/*
+- * Here we define a transition notifier so that we can update all of our
+- * ports' baud rate when the peripheral clock changes.
+- */
+-static int sci_notifier(struct notifier_block *self,
+-                      unsigned long phase, void *p)
+-{
+-      struct sci_port *sci_port;
+-      unsigned long flags;
+-
+-      sci_port = container_of(self, struct sci_port, freq_transition);
+-
+-      if ((phase == CPUFREQ_POSTCHANGE) ||
+-          (phase == CPUFREQ_RESUMECHANGE)) {
+-              struct uart_port *port = &sci_port->port;
+-
+-              spin_lock_irqsave(&port->lock, flags);
+-              port->uartclk = clk_get_rate(sci_port->iclk);
+-              spin_unlock_irqrestore(&port->lock, flags);
+-      }
+-
+-      return NOTIFY_OK;
+-}
+-
+ static struct sci_irq_desc {
+       const char      *desc;
+       irq_handler_t   handler;
+@@ -2406,9 +2379,6 @@ static int sci_remove(struct platform_de
+ {
+       struct sci_port *port = platform_get_drvdata(dev);
+-      cpufreq_unregister_notifier(&port->freq_transition,
+-                                  CPUFREQ_TRANSITION_NOTIFIER);
+-
+       uart_remove_one_port(&sci_uart_driver, &port->port);
+       sci_cleanup_single(port);
+@@ -2559,15 +2529,6 @@ static int sci_probe(struct platform_dev
+       if (ret)
+               return ret;
+-      sp->freq_transition.notifier_call = sci_notifier;
+-
+-      ret = cpufreq_register_notifier(&sp->freq_transition,
+-                                      CPUFREQ_TRANSITION_NOTIFIER);
+-      if (unlikely(ret < 0)) {
+-              sci_cleanup_single(sp);
+-              return ret;
+-      }
+-
+ #ifdef CONFIG_SH_STANDARD_BIOS
+       sh_bios_gdb_detach();
+ #endif
index 873ae889be9e19c430752a06a8a0cc4b74dbbbd2..fdd7b9ba8e9816d0138113827f13a7c27fb71c5d 100644 (file)
@@ -26,3 +26,6 @@ rtc-hym8563-fix-invalid-year-calculation.patch
 rtc-vr41xx-wire-up-alarm_irq_enable.patch
 drivers-misc-ad525x_dpot-ad5274-fix-rdac-read-back-errors.patch
 ext4-fix-null-pointer-dereference-in-ext4_mark_inode_dirty.patch
+serial-sh-sci-remove-cpufreq-notifier-to-fix-crash-deadlock.patch
+include-linux-poison.h-fix-list_poison-1-2-offset.patch
+drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hypervisors.patch