From: Greg Kroah-Hartman Date: Thu, 19 Oct 2017 09:25:41 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.77~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f9f422dcc4c86cd1cbe07bfa4832d8f625738ff3;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch --- diff --git a/queue-4.4/percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch b/queue-4.4/percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch new file mode 100644 index 00000000000..6b6e464945c --- /dev/null +++ b/queue-4.4/percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch @@ -0,0 +1,81 @@ +From e88d62cd4b2f0b1ae55e9008e79c2794b1fc914d Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Tue, 26 Sep 2017 12:41:52 +0100 +Subject: percpu: make this_cpu_generic_read() atomic w.r.t. interrupts + +From: Mark Rutland + +commit e88d62cd4b2f0b1ae55e9008e79c2794b1fc914d upstream. + +As raw_cpu_generic_read() is a plain read from a raw_cpu_ptr() address, +it's possible (albeit unlikely) that the compiler will split the access +across multiple instructions. + +In this_cpu_generic_read() we disable preemption but not interrupts +before calling raw_cpu_generic_read(). Thus, an interrupt could be taken +in the middle of the split load instructions. If a this_cpu_write() or +RMW this_cpu_*() op is made to the same variable in the interrupt +handling path, this_cpu_read() will return a torn value. + +For native word types, we can avoid tearing using READ_ONCE(), but this +won't work in all cases (e.g. 64-bit types on most 32-bit platforms). +This patch reworks this_cpu_generic_read() to use READ_ONCE() where +possible, otherwise falling back to disabling interrupts. + +Signed-off-by: Mark Rutland +Cc: Arnd Bergmann +Cc: Christoph Lameter +Cc: Peter Zijlstra +Cc: Pranith Kumar +Cc: Tejun Heo +Cc: Thomas Gleixner +Cc: linux-arch@vger.kernel.org +Signed-off-by: Tejun Heo +[Mark: backport to v4.4.y] +Signed-off-by: Mark Rutland +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/percpu.h | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/include/asm-generic/percpu.h ++++ b/include/asm-generic/percpu.h +@@ -105,15 +105,35 @@ do { \ + (__ret); \ + }) + +-#define this_cpu_generic_read(pcp) \ ++#define __this_cpu_generic_read_nopreempt(pcp) \ + ({ \ + typeof(pcp) __ret; \ + preempt_disable(); \ +- __ret = *this_cpu_ptr(&(pcp)); \ ++ __ret = READ_ONCE(*raw_cpu_ptr(&(pcp))); \ + preempt_enable(); \ + __ret; \ + }) + ++#define __this_cpu_generic_read_noirq(pcp) \ ++({ \ ++ typeof(pcp) __ret; \ ++ unsigned long __flags; \ ++ raw_local_irq_save(__flags); \ ++ __ret = *raw_cpu_ptr(&(pcp)); \ ++ raw_local_irq_restore(__flags); \ ++ __ret; \ ++}) ++ ++#define this_cpu_generic_read(pcp) \ ++({ \ ++ typeof(pcp) __ret; \ ++ if (__native_word(pcp)) \ ++ __ret = __this_cpu_generic_read_nopreempt(pcp); \ ++ else \ ++ __ret = __this_cpu_generic_read_noirq(pcp); \ ++ __ret; \ ++}) ++ + #define this_cpu_generic_to_op(pcp, val, op) \ + do { \ + unsigned long __flags; \ diff --git a/queue-4.4/series b/queue-4.4/series new file mode 100644 index 00000000000..a490ef2541d --- /dev/null +++ b/queue-4.4/series @@ -0,0 +1 @@ +percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch