From: Greg Kroah-Hartman Date: Tue, 10 Oct 2017 14:32:04 +0000 (+0200) Subject: 4.13-stable patches X-Git-Tag: v3.18.75~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a9bbbc920da01876d5969462247fcbefcbcecff2;p=thirdparty%2Fkernel%2Fstable-queue.git 4.13-stable patches added patches: percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch --- diff --git a/queue-4.13/percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch b/queue-4.13/percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch new file mode 100644 index 00000000000..09930e732e2 --- /dev/null +++ b/queue-4.13/percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch @@ -0,0 +1,79 @@ +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 +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 +@@ -115,15 +115,35 @@ do { \ + (__ret); \ + }) + +-#define this_cpu_generic_read(pcp) \ ++#define __this_cpu_generic_read_nopreempt(pcp) \ + ({ \ + typeof(pcp) __ret; \ + preempt_disable_notrace(); \ +- __ret = raw_cpu_generic_read(pcp); \ ++ __ret = READ_ONCE(*raw_cpu_ptr(&(pcp))); \ + preempt_enable_notrace(); \ + __ret; \ + }) + ++#define __this_cpu_generic_read_noirq(pcp) \ ++({ \ ++ typeof(pcp) __ret; \ ++ unsigned long __flags; \ ++ raw_local_irq_save(__flags); \ ++ __ret = raw_cpu_generic_read(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.13/series b/queue-4.13/series index 004f58e6af4..e060e0b2a5b 100644 --- a/queue-4.13/series +++ b/queue-4.13/series @@ -109,3 +109,4 @@ powerpc-powernv-increase-memory-block-size-to-1gb-on-radix.patch powerpc-fix-action-argument-for-cpufeatures-based-tlb-flush.patch powerpc-64s-use-emergency-stack-for-kernel-tm-bad-thing-program-checks.patch powerpc-tm-fix-illegal-tm-state-in-signal-handler.patch +percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch