]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Oct 2017 09:25:41 +0000 (11:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Oct 2017 09:25:41 +0000 (11:25 +0200)
added patches:
percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch

queue-4.4/percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch [new file with mode: 0644]
queue-4.4/series [new file with mode: 0644]

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 (file)
index 0000000..6b6e464
--- /dev/null
@@ -0,0 +1,81 @@
+From e88d62cd4b2f0b1ae55e9008e79c2794b1fc914d Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Tue, 26 Sep 2017 12:41:52 +0100
+Subject: percpu: make this_cpu_generic_read() atomic w.r.t. interrupts
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+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 <mark.rutland@arm.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Pranith Kumar <bobby.prani@gmail.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-arch@vger.kernel.org
+Signed-off-by: Tejun Heo <tj@kernel.org>
+[Mark: backport to v4.4.y]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a490ef2
--- /dev/null
@@ -0,0 +1 @@
+percpu-make-this_cpu_generic_read-atomic-w.r.t.-interrupts.patch