From aefe86bde9620f632865120eb28b8cc95e9f5992 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 29 Feb 2016 23:12:37 -0800 Subject: [PATCH] 3.10-stable patches added patches: clocksource-drivers-vt8500-increase-the-minimum-delta.patch dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch genirq-prevent-chip-buslock-deadlock.patch --- ...rs-vt8500-increase-the-minimum-delta.patch | 81 +++++++++++++++++++ ...add-sdhc-node-to-dts-file-for-wm8650.patch | 40 +++++++++ ...genirq-prevent-chip-buslock-deadlock.patch | 80 ++++++++++++++++++ queue-3.10/series | 3 + 4 files changed, 204 insertions(+) create mode 100644 queue-3.10/clocksource-drivers-vt8500-increase-the-minimum-delta.patch create mode 100644 queue-3.10/dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch create mode 100644 queue-3.10/genirq-prevent-chip-buslock-deadlock.patch diff --git a/queue-3.10/clocksource-drivers-vt8500-increase-the-minimum-delta.patch b/queue-3.10/clocksource-drivers-vt8500-increase-the-minimum-delta.patch new file mode 100644 index 00000000000..c9d1826b725 --- /dev/null +++ b/queue-3.10/clocksource-drivers-vt8500-increase-the-minimum-delta.patch @@ -0,0 +1,81 @@ +From f9eccf24615672896dc13251410c3f2f33a14f95 Mon Sep 17 00:00:00 2001 +From: Roman Volkov +Date: Fri, 1 Jan 2016 16:24:41 +0300 +Subject: clocksource/drivers/vt8500: Increase the minimum delta + +From: Roman Volkov + +commit f9eccf24615672896dc13251410c3f2f33a14f95 upstream. + +The vt8500 clocksource driver declares itself as capable to handle the +minimum delay of 4 cycles by passing the value into +clockevents_config_and_register(). The vt8500_timer_set_next_event() +requires the passed cycles value to be at least 16. The impact is that +userspace hangs in nanosleep() calls with small delay intervals. + +This problem is reproducible in Linux 4.2 starting from: +c6eb3f70d448 ('hrtimer: Get rid of hrtimer softirq') + +From Russell King, more detailed explanation: + +"It's a speciality of the StrongARM/PXA hardware. It takes a certain +number of OSCR cycles for the value written to hit the compare registers. +So, if a very small delta is written (eg, the compare register is written +with a value of OSCR + 1), the OSCR will have incremented past this value +before it hits the underlying hardware. The result is, that you end up +waiting a very long time for the OSCR to wrap before the event fires. + +So, we introduce a check in set_next_event() to detect this and return +-ETIME if the calculated delta is too small, which causes the generic +clockevents code to retry after adding the min_delta specified in +clockevents_config_and_register() to the current time value. + +min_delta must be sufficient that we don't re-trip the -ETIME check - if +we do, we will return -ETIME, forward the next event time, try to set it, +return -ETIME again, and basically lock the system up. So, min_delta +must be larger than the check inside set_next_event(). A factor of two +was chosen to ensure that this situation would never occur. + +The PXA code worked on PXA systems for years, and I'd suggest no one +changes this mechanism without access to a wide range of PXA systems, +otherwise they're risking breakage." + +Cc: Russell King +Acked-by: Alexey Charkov +Signed-off-by: Roman Volkov +Signed-off-by: Daniel Lezcano +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clocksource/vt8500_timer.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/clocksource/vt8500_timer.c ++++ b/drivers/clocksource/vt8500_timer.c +@@ -50,6 +50,8 @@ + + #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + ++#define MIN_OSCR_DELTA 16 ++ + static void __iomem *regbase; + + static cycle_t vt8500_timer_read(struct clocksource *cs) +@@ -80,7 +82,7 @@ static int vt8500_timer_set_next_event(u + cpu_relax(); + writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL); + +- if ((signed)(alarm - clocksource.read(&clocksource)) <= 16) ++ if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA) + return -ETIME; + + writel(1, regbase + TIMER_IER_VAL); +@@ -162,7 +164,7 @@ static void __init vt8500_timer_init(str + pr_err("%s: setup_irq failed for %s\n", __func__, + clockevent.name); + clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ, +- 4, 0xf0000000); ++ MIN_OSCR_DELTA * 2, 0xf0000000); + } + + CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); diff --git a/queue-3.10/dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch b/queue-3.10/dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch new file mode 100644 index 00000000000..50de5dbbad0 --- /dev/null +++ b/queue-3.10/dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch @@ -0,0 +1,40 @@ +From 0f090bf14e51e7eefb71d9d1c545807f8b627986 Mon Sep 17 00:00:00 2001 +From: Roman Volkov +Date: Fri, 1 Jan 2016 16:38:11 +0300 +Subject: dts: vt8500: Add SDHC node to DTS file for WM8650 + +From: Roman Volkov + +commit 0f090bf14e51e7eefb71d9d1c545807f8b627986 upstream. + +Since WM8650 has the same 'WMT' SDHC controller as WM8505, and the driver +is already in the kernel, this node enables the controller support for +WM8650 + +Signed-off-by: Roman Volkov +Reviewed-by: Alexey Charkov +Signed-off-by: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/wm8650.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/arch/arm/boot/dts/wm8650.dtsi ++++ b/arch/arm/boot/dts/wm8650.dtsi +@@ -130,6 +130,15 @@ + interrupts = <43>; + }; + ++ sdhc@d800a000 { ++ compatible = "wm,wm8505-sdhc"; ++ reg = <0xd800a000 0x400>; ++ interrupts = <20>, <21>; ++ clocks = <&clksdhc>; ++ bus-width = <4>; ++ sdon-inverted; ++ }; ++ + fb: fb@d8050800 { + compatible = "wm,wm8505-fb"; + reg = <0xd8050800 0x200>; diff --git a/queue-3.10/genirq-prevent-chip-buslock-deadlock.patch b/queue-3.10/genirq-prevent-chip-buslock-deadlock.patch new file mode 100644 index 00000000000..57b370febed --- /dev/null +++ b/queue-3.10/genirq-prevent-chip-buslock-deadlock.patch @@ -0,0 +1,80 @@ +From abc7e40c81d113ef4bacb556f0a77ca63ac81d85 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Sun, 13 Dec 2015 18:12:30 +0100 +Subject: genirq: Prevent chip buslock deadlock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Gleixner + +commit abc7e40c81d113ef4bacb556f0a77ca63ac81d85 upstream. + +If a interrupt chip utilizes chip->buslock then free_irq() can +deadlock in the following way: + +CPU0 CPU1 + interrupt(X) (Shared or spurious) +free_irq(X) interrupt_thread(X) +chip_bus_lock(X) + irq_finalize_oneshot(X) + chip_bus_lock(X) +synchronize_irq(X) + +synchronize_irq() waits for the interrupt thread to complete, +i.e. forever. + +Solution is simple: Drop chip_bus_lock() before calling +synchronize_irq() as we do with the irq_desc lock. There is nothing to +be protected after the point where irq_desc lock has been released. + +This adds chip_bus_lock/unlock() to the remove_irq() code path, but +that's actually correct in the case where remove_irq() is called on +such an interrupt. The current users of remove_irq() are not affected +as none of those interrupts is on a chip which requires buslock. + +Reported-by: Fredrik Markström +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/irq/manage.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -1229,6 +1229,7 @@ static struct irqaction *__free_irq(unsi + if (!desc) + return NULL; + ++ chip_bus_lock(desc); + raw_spin_lock_irqsave(&desc->lock, flags); + + /* +@@ -1242,7 +1243,7 @@ static struct irqaction *__free_irq(unsi + if (!action) { + WARN(1, "Trying to free already-free IRQ %d\n", irq); + raw_spin_unlock_irqrestore(&desc->lock, flags); +- ++ chip_bus_sync_unlock(desc); + return NULL; + } + +@@ -1265,6 +1266,7 @@ static struct irqaction *__free_irq(unsi + #endif + + raw_spin_unlock_irqrestore(&desc->lock, flags); ++ chip_bus_sync_unlock(desc); + + unregister_handler_proc(irq, action); + +@@ -1338,9 +1340,7 @@ void free_irq(unsigned int irq, void *de + desc->affinity_notify = NULL; + #endif + +- chip_bus_lock(desc); + kfree(__free_irq(irq, dev_id)); +- chip_bus_sync_unlock(desc); + } + EXPORT_SYMBOL(free_irq); + diff --git a/queue-3.10/series b/queue-3.10/series index 7a42adabf3b..41b3e7efe00 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -19,3 +19,6 @@ mips-kvm-uninit-vcpu-in-vcpu_create-error-path.patch splice-sendfile-at-once-fails-for-big-files.patch failing-to-send-a-close-if-file-is-opened-wronly-and-server-reboots-on-a-4.x-mount.patch unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch +genirq-prevent-chip-buslock-deadlock.patch +dts-vt8500-add-sdhc-node-to-dts-file-for-wm8650.patch +clocksource-drivers-vt8500-increase-the-minimum-delta.patch -- 2.47.3