--- /dev/null
+From f9eccf24615672896dc13251410c3f2f33a14f95 Mon Sep 17 00:00:00 2001
+From: Roman Volkov <rvolkov@v1ros.org>
+Date: Fri, 1 Jan 2016 16:24:41 +0300
+Subject: clocksource/drivers/vt8500: Increase the minimum delta
+
+From: Roman Volkov <rvolkov@v1ros.org>
+
+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 <linux@arm.linux.org.uk>
+Acked-by: Alexey Charkov <alchark@gmail.com>
+Signed-off-by: Roman Volkov <rvolkov@v1ros.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+@@ -151,7 +153,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);
--- /dev/null
+From 570540d50710ed192e98e2f7f74578c9486b6b05 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Wed, 13 Jan 2016 14:07:25 +0100
+Subject: genirq: Validate action before dereferencing it in handle_irq_event_percpu()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 570540d50710ed192e98e2f7f74578c9486b6b05 upstream.
+
+commit 71f64340fc0e changed the handling of irq_desc->action from
+
+CPU 0 CPU 1
+free_irq() lock(desc)
+ lock(desc) handle_edge_irq()
+ if (desc->action) {
+ handle_irq_event()
+ action = desc->action
+ unlock(desc)
+ desc->action = NULL handle_irq_event_percpu(desc, action)
+ action->xxx
+to
+
+CPU 0 CPU 1
+free_irq() lock(desc)
+ lock(desc) handle_edge_irq()
+ if (desc->action) {
+ handle_irq_event()
+ unlock(desc)
+ desc->action = NULL handle_irq_event_percpu(desc, action)
+ action = desc->action
+ action->xxx
+
+So if free_irq manages to set the action to NULL between the unlock and before
+the readout, we happily dereference a null pointer.
+
+We could simply revert 71f64340fc0e, but we want to preserve the better code
+generation. A simple solution is to change the action loop from a do {} while
+to a while {} loop.
+
+This is safe because we either see a valid desc->action or NULL. If the action
+is about to be removed it is still valid as free_irq() is blocked on
+synchronize_irq().
+
+CPU 0 CPU 1
+free_irq() lock(desc)
+ lock(desc) handle_edge_irq()
+ handle_irq_event(desc)
+ set(INPROGRESS)
+ unlock(desc)
+ handle_irq_event_percpu(desc)
+ action = desc->action
+ desc->action = NULL while (action) {
+ action->xxx
+ ...
+ action = action->next;
+ sychronize_irq()
+ while(INPROGRESS); lock(desc)
+ clr(INPROGRESS)
+free(action)
+
+That's basically the same mechanism as we have for shared
+interrupts. action->next can become NULL while handle_irq_event_percpu()
+runs. Either it sees the action or NULL. It does not matter, because action
+itself cannot go away before the interrupt in progress flag has been cleared.
+
+Fixes: commit 71f64340fc0e "genirq: Remove the second parameter from handle_irq_event_percpu()"
+Reported-by: zyjzyj2000@gmail.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Huang Shijie <shijie.huang@arm.com>
+Cc: Jiang Liu <jiang.liu@linux.intel.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1601131224190.3575@nanos
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/handle.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/kernel/irq/handle.c
++++ b/kernel/irq/handle.c
+@@ -138,7 +138,8 @@ irqreturn_t handle_irq_event_percpu(stru
+ unsigned int flags = 0, irq = desc->irq_data.irq;
+ struct irqaction *action = desc->action;
+
+- do {
++ /* action might have become NULL since we dropped the lock */
++ while (action) {
+ irqreturn_t res;
+
+ trace_irq_handler_entry(irq, action);
+@@ -173,7 +174,7 @@ irqreturn_t handle_irq_event_percpu(stru
+
+ retval |= res;
+ action = action->next;
+- } while (action);
++ }
+
+ add_interrupt_randomness(irq, flags);
+