From fa09ea91133297b5a1c87f1e9a3cfa85e3da457f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 2 May 2016 14:17:19 -0700 Subject: [PATCH] 3.14-stable patches 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 --- ...t-cpu-offlining-on-newer-hypervisors.patch | 97 ++++++++++++++ ...-poison.h-fix-list_poison-1-2-offset.patch | 49 +++++++ ...ufreq-notifier-to-fix-crash-deadlock.patch | 124 ++++++++++++++++++ queue-3.14/series | 3 + 4 files changed, 273 insertions(+) create mode 100644 queue-3.14/drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hypervisors.patch create mode 100644 queue-3.14/include-linux-poison.h-fix-list_poison-1-2-offset.patch create mode 100644 queue-3.14/serial-sh-sci-remove-cpufreq-notifier-to-fix-crash-deadlock.patch 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 index 00000000000..c39d946a0e1 --- /dev/null +++ b/queue-3.14/drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hypervisors.patch @@ -0,0 +1,97 @@ +From e513229b4c386e6c9f66298c13fde92f73e6e1ac Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Fri, 27 Feb 2015 11:25:51 -0800 +Subject: Drivers: hv: vmbus: prevent cpu offlining on newer hypervisors + +From: Vitaly Kuznetsov + +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 +Signed-off-by: K. Y. Srinivasan +[ 3chas3@gmail.com: rebase to 3.14-stable ] +Signed-off-by: Chas Williams <3chas3@gmail.com> +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -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 index 00000000000..dbf43a5d65a --- /dev/null +++ b/queue-3.14/include-linux-poison.h-fix-list_poison-1-2-offset.patch @@ -0,0 +1,49 @@ +From 8a5e5e02fc83aaf67053ab53b359af08c6c49aaf Mon Sep 17 00:00:00 2001 +From: Vasily Kulikov +Date: Wed, 9 Sep 2015 15:36:00 -0700 +Subject: include/linux/poison.h: fix LIST_POISON{1,2} offset + +From: Vasily Kulikov + +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 +Cc: Solar Designer +Cc: Thomas Gleixner +Cc: "Kirill A. Shutemov" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..42f4ffe293c --- /dev/null +++ b/queue-3.14/serial-sh-sci-remove-cpufreq-notifier-to-fix-crash-deadlock.patch @@ -0,0 +1,124 @@ +From ff1cab374ad98f4b9f408525ca9c08992b4ed784 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Tue, 5 Jan 2016 19:36:37 +0100 +Subject: serial: sh-sci: Remove cpufreq notifier to fix crash/deadlock + +From: Geert Uytterhoeven + +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 +Signed-off-by: Greg Kroah-Hartman + + + +--- + 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 + #include + #include +-#include + #include + #include + #include +@@ -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 diff --git a/queue-3.14/series b/queue-3.14/series index 873ae889be9..fdd7b9ba8e9 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -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 -- 2.47.2