diff mbox series

[15/16] kfence, x86: fix preemptible warning on KPTI-enabled systems

Message ID 20210409202744.raBMoNOTx%akpm@linux-foundation.org (mailing list archive)
State New
Headers show
Series [01/16] MAINTAINERS: update CZ.NIC's Turris information | expand

Commit Message

Andrew Morton April 9, 2021, 8:27 p.m. UTC
From: Marco Elver <elver@google.com>
Subject: kfence, x86: fix preemptible warning on KPTI-enabled systems

On systems with KPTI enabled, we can currently observe the following

  BUG: using smp_processor_id() in preemptible
  caller is invalidate_user_asid+0x13/0x50
  CPU: 6 PID: 1075 Comm: dmesg Not tainted 5.12.0-rc4-gda4a2b1a5479-kfence_1+ #1
  Hardware name: Hewlett-Packard HP Pro 3500 Series/2ABF, BIOS 8.11 10/24/2012
  Call Trace:

While it normally makes sense to require preemption to be off, so that the
expected CPU's TLB is flushed and not another, in our case it really is
best-effort (see comments in kfence_protect_page()).

Avoid the warning by disabling preemption around flush_tlb_one_kernel().

Link: https://lore.kernel.org/lkml/YGIDBAboELGgMgXy@elver.google.com/
Link: https://lkml.kernel.org/r/20210330065737.652669-1-elver@google.com
Signed-off-by: Marco Elver <elver@google.com>
Reported-by: Tomi Sarvela <tomi.p.sarvela@intel.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Andrey Konovalov <andreyknvl@google.com>
Cc: Jann Horn <jannh@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

 arch/x86/include/asm/kfence.h |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
diff mbox series


--- a/arch/x86/include/asm/kfence.h~kfence-x86-fix-preemptible-warning-on-kpti-enabled-systems
+++ a/arch/x86/include/asm/kfence.h
@@ -56,8 +56,13 @@  static inline bool kfence_protect_page(u
 		set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));
-	/* Flush this CPU's TLB. */
+	/*
+	 * Flush this CPU's TLB, assuming whoever did the allocation/free is
+	 * likely to continue running on this CPU.
+	 */
+	preempt_disable();
+	preempt_enable();
 	return true;