All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	rostedt@goodmis.org
Cc: peterz@infradead.org, mingo@kernel.org, joel@joelfernandes.org,
	gregkh@linuxfoundation.org, gustavo@embeddedor.com,
	tglx@linutronix.de, paulmck@kernel.org, josh@joshtriplett.org,
	mathieu.desnoyers@efficios.com, jiangshanlai@gmail.com,
	luto@kernel.org, tony.luck@intel.com, frederic@kernel.org,
	dan.carpenter@oracle.com, mhiramat@kernel.org,
	Will Deacon <will@kernel.org>, Petr Mladek <pmladek@suse.com>,
	Marc Zyngier <maz@kernel.org>
Subject: [PATCH v4 02/27] hardirq/nmi: Allow nested nmi_enter()
Date: Fri, 21 Feb 2020 14:34:18 +0100	[thread overview]
Message-ID: <20200221134215.149193474@infradead.org> (raw)
In-Reply-To: 20200221133416.777099322@infradead.org

Since there are already a number of sites (ARM64, PowerPC) that
effectively nest nmi_enter(), lets make the primitive support this
before adding even more.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/hardirq.h |    4 ++--
 arch/arm64/kernel/sdei.c         |   14 ++------------
 arch/arm64/kernel/traps.c        |    8 ++------
 arch/powerpc/kernel/traps.c      |   22 ++++++----------------
 include/linux/hardirq.h          |    5 ++++-
 include/linux/preempt.h          |    4 ++--
 kernel/printk/printk_safe.c      |    6 ++++--
 7 files changed, 22 insertions(+), 41 deletions(-)

--- a/arch/arm64/include/asm/hardirq.h
+++ b/arch/arm64/include/asm/hardirq.h
@@ -38,7 +38,7 @@ DECLARE_PER_CPU(struct nmi_ctx, nmi_cont
 
 #define arch_nmi_enter()							\
 	do {									\
-		if (is_kernel_in_hyp_mode()) {					\
+		if (is_kernel_in_hyp_mode() && !in_nmi()) {			\
 			struct nmi_ctx *nmi_ctx = this_cpu_ptr(&nmi_contexts);	\
 			nmi_ctx->hcr = read_sysreg(hcr_el2);			\
 			if (!(nmi_ctx->hcr & HCR_TGE)) {			\
@@ -50,7 +50,7 @@ DECLARE_PER_CPU(struct nmi_ctx, nmi_cont
 
 #define arch_nmi_exit()								\
 	do {									\
-		if (is_kernel_in_hyp_mode()) {					\
+		if (is_kernel_in_hyp_mode() && !in_nmi()) {			\
 			struct nmi_ctx *nmi_ctx = this_cpu_ptr(&nmi_contexts);	\
 			if (!(nmi_ctx->hcr & HCR_TGE))				\
 				write_sysreg(nmi_ctx->hcr, hcr_el2);		\
--- a/arch/arm64/kernel/sdei.c
+++ b/arch/arm64/kernel/sdei.c
@@ -251,22 +251,12 @@ asmlinkage __kprobes notrace unsigned lo
 __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
 {
 	unsigned long ret;
-	bool do_nmi_exit = false;
 
-	/*
-	 * nmi_enter() deals with printk() re-entrance and use of RCU when
-	 * RCU believed this CPU was idle. Because critical events can
-	 * interrupt normal events, we may already be in_nmi().
-	 */
-	if (!in_nmi()) {
-		nmi_enter();
-		do_nmi_exit = true;
-	}
+	nmi_enter();
 
 	ret = _sdei_handler(regs, arg);
 
-	if (do_nmi_exit)
-		nmi_exit();
+	nmi_exit();
 
 	return ret;
 }
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -906,17 +906,13 @@ bool arm64_is_fatal_ras_serror(struct pt
 
 asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
 {
-	const bool was_in_nmi = in_nmi();
-
-	if (!was_in_nmi)
-		nmi_enter();
+	nmi_enter();
 
 	/* non-RAS errors are not containable */
 	if (!arm64_is_ras_serror(esr) || arm64_is_fatal_ras_serror(regs, esr))
 		arm64_serror_panic(regs, esr);
 
-	if (!was_in_nmi)
-		nmi_exit();
+	nmi_exit();
 }
 
 asmlinkage void enter_from_user_mode(void)
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -441,15 +441,9 @@ void hv_nmi_check_nonrecoverable(struct
 void system_reset_exception(struct pt_regs *regs)
 {
 	unsigned long hsrr0, hsrr1;
-	bool nested = in_nmi();
 	bool saved_hsrrs = false;
 
-	/*
-	 * Avoid crashes in case of nested NMI exceptions. Recoverability
-	 * is determined by RI and in_nmi
-	 */
-	if (!nested)
-		nmi_enter();
+	nmi_enter();
 
 	/*
 	 * System reset can interrupt code where HSRRs are live and MSR[RI]=1.
@@ -521,8 +515,7 @@ void system_reset_exception(struct pt_re
 		mtspr(SPRN_HSRR1, hsrr1);
 	}
 
-	if (!nested)
-		nmi_exit();
+	nmi_exit();
 
 	/* What should we do here? We could issue a shutdown or hard reset. */
 }
@@ -823,9 +816,8 @@ int machine_check_generic(struct pt_regs
 void machine_check_exception(struct pt_regs *regs)
 {
 	int recover = 0;
-	bool nested = in_nmi();
-	if (!nested)
-		nmi_enter();
+
+	nmi_enter();
 
 	__this_cpu_inc(irq_stat.mce_exceptions);
 
@@ -851,8 +843,7 @@ void machine_check_exception(struct pt_r
 	if (check_io_access(regs))
 		goto bail;
 
-	if (!nested)
-		nmi_exit();
+	nmi_exit();
 
 	die("Machine check", regs, SIGBUS);
 
@@ -863,8 +854,7 @@ void machine_check_exception(struct pt_r
 	return;
 
 bail:
-	if (!nested)
-		nmi_exit();
+	nmi_exit();
 }
 
 void SMIException(struct pt_regs *regs)
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -65,13 +65,16 @@ extern void irq_exit(void);
 #define arch_nmi_exit()		do { } while (0)
 #endif
 
+/*
+ * nmi_enter() can nest up to 15 times; see NMI_BITS.
+ */
 #define nmi_enter()						\
 	do {							\
 		arch_nmi_enter();				\
 		printk_nmi_enter();				\
 		lockdep_off();					\
 		ftrace_nmi_enter();				\
-		BUG_ON(in_nmi());				\
+		BUG_ON(in_nmi() == NMI_MASK);			\
 		preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET);	\
 		rcu_nmi_enter();				\
 		trace_hardirq_enter();				\
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -26,13 +26,13 @@
  *         PREEMPT_MASK:	0x000000ff
  *         SOFTIRQ_MASK:	0x0000ff00
  *         HARDIRQ_MASK:	0x000f0000
- *             NMI_MASK:	0x00100000
+ *             NMI_MASK:	0x00f00000
  * PREEMPT_NEED_RESCHED:	0x80000000
  */
 #define PREEMPT_BITS	8
 #define SOFTIRQ_BITS	8
 #define HARDIRQ_BITS	4
-#define NMI_BITS	1
+#define NMI_BITS	4
 
 #define PREEMPT_SHIFT	0
 #define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
--- a/kernel/printk/printk_safe.c
+++ b/kernel/printk/printk_safe.c
@@ -296,12 +296,14 @@ static __printf(1, 0) int vprintk_nmi(co
 
 void notrace printk_nmi_enter(void)
 {
-	this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK);
+	if (!in_nmi())
+		this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK);
 }
 
 void notrace printk_nmi_exit(void)
 {
-	this_cpu_and(printk_context, ~PRINTK_NMI_CONTEXT_MASK);
+	if (!in_nmi())
+		this_cpu_and(printk_context, ~PRINTK_NMI_CONTEXT_MASK);
 }
 
 /*



  parent reply	other threads:[~2020-02-21 13:50 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-21 13:34 [PATCH v4 00/27] tracing vs world Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 01/27] lockdep: Teach lockdep about "USED" <- "IN-NMI" inversions Peter Zijlstra
2020-02-21 15:08   ` Steven Rostedt
2020-02-21 20:25     ` Peter Zijlstra
2020-02-21 20:28       ` Steven Rostedt
2020-02-21 22:01       ` Frederic Weisbecker
2020-02-22  3:08   ` Joel Fernandes
2020-02-24 10:10     ` Peter Zijlstra
2020-02-25  2:12       ` Joel Fernandes
2020-03-20 12:58   ` [tip: locking/core] " tip-bot2 for Peter Zijlstra
2020-02-21 13:34 ` Peter Zijlstra [this message]
2020-02-21 22:21   ` [PATCH v4 02/27] hardirq/nmi: Allow nested nmi_enter() Frederic Weisbecker
2020-02-24 12:13     ` Petr Mladek
2020-02-25  1:30       ` Frederic Weisbecker
2020-02-24 16:13     ` Peter Zijlstra
2020-02-25  3:09       ` Frederic Weisbecker
2020-02-25 15:41         ` Peter Zijlstra
2020-02-25 16:21           ` Frederic Weisbecker
2020-02-25 22:10           ` Frederic Weisbecker
2020-02-27  9:10             ` Peter Zijlstra
2020-02-27 13:34               ` Frederic Weisbecker
2020-02-21 13:34 ` [PATCH v4 03/27] x86/entry: Flip _TIF_SIGPENDING and _TIF_NOTIFY_RESUME handling Peter Zijlstra
2020-02-21 16:14   ` Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 04/27] x86/mce: Delete ist_begin_non_atomic() Peter Zijlstra
2020-02-21 19:07   ` Andy Lutomirski
2020-02-21 23:40   ` Frederic Weisbecker
2020-02-21 13:34 ` [PATCH v4 05/27] x86: Replace ist_enter() with nmi_enter() Peter Zijlstra
2020-02-21 19:05   ` Andy Lutomirski
2020-02-21 20:22     ` Peter Zijlstra
2020-02-24 10:43       ` Peter Zijlstra
2020-02-24 16:27         ` Steven Rostedt
2020-02-24 16:34           ` Peter Zijlstra
2020-02-24 16:47             ` Steven Rostedt
2020-02-24 21:31               ` Peter Zijlstra
2020-02-24 22:02                 ` Steven Rostedt
2020-02-26 10:25                   ` Peter Zijlstra
2020-02-26 13:16                     ` Peter Zijlstra
2020-02-26 10:27                   ` Peter Zijlstra
2020-02-26 15:20                     ` Steven Rostedt
2020-03-07  1:53                     ` Masami Hiramatsu
2020-02-21 13:34 ` [PATCH v4 06/27] x86/doublefault: Remove memmove() call Peter Zijlstra
2020-02-21 19:10   ` Andy Lutomirski
2020-02-21 13:34 ` [PATCH v4 07/27] rcu: Make RCU IRQ enter/exit functions rely on in_nmi() Peter Zijlstra
2020-02-26  0:23   ` Frederic Weisbecker
2020-02-21 13:34 ` [PATCH v4 08/27] rcu/kprobes: Comment why rcu_nmi_enter() is marked NOKPROBE Peter Zijlstra
2020-02-26  0:27   ` Frederic Weisbecker
2020-02-21 13:34 ` [PATCH v4 09/27] rcu: Rename rcu_irq_{enter,exit}_irqson() Peter Zijlstra
2020-02-21 20:21   ` Steven Rostedt
2020-02-24 10:24     ` Peter Zijlstra
2020-02-26  0:35   ` Frederic Weisbecker
2020-02-21 13:34 ` [PATCH v4 10/27] rcu: Mark rcu_dynticks_curr_cpu_in_eqs() inline Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 11/27] rcu,tracing: Create trace_rcu_{enter,exit}() Peter Zijlstra
2020-03-06 11:50   ` Peter Zijlstra
2020-03-06 12:40     ` Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 12/27] sched,rcu,tracing: Avoid tracing before in_nmi() is correct Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 13/27] x86,tracing: Add comments to do_nmi() Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 14/27] perf,tracing: Prepare the perf-trace interface for RCU changes Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 15/27] tracing: Employ trace_rcu_{enter,exit}() Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 16/27] tracing: Remove regular RCU context for _rcuidle tracepoints (again) Peter Zijlstra
2020-03-06 10:43   ` Peter Zijlstra
2020-03-06 11:31     ` Peter Zijlstra
2020-03-06 15:51       ` Alexei Starovoitov
2020-03-06 16:04         ` Mathieu Desnoyers
2020-03-06 17:55           ` Steven Rostedt
2020-03-06 18:45             ` Joel Fernandes
2020-03-06 18:59               ` Steven Rostedt
2020-03-06 19:14                 ` Joel Fernandes
2020-03-06 20:22             ` Mathieu Desnoyers
2020-03-06 20:45               ` Steven Rostedt
2020-03-06 20:55                 ` Mathieu Desnoyers
2020-03-06 21:06                   ` Steven Rostedt
2020-03-06 23:10                   ` Alexei Starovoitov
2020-03-06 17:21         ` Joel Fernandes
2020-02-21 13:34 ` [PATCH v4 17/27] perf,tracing: Allow function tracing when !RCU Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 18/27] x86/int3: Ensure that poke_int3_handler() is not traced Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 19/27] locking/atomics, kcsan: Add KCSAN instrumentation Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 20/27] asm-generic/atomic: Use __always_inline for pure wrappers Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 21/27] asm-generic/atomic: Use __always_inline for fallback wrappers Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 22/27] compiler: Simple READ/WRITE_ONCE() implementations Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 23/27] locking/atomics: Flip fallbacks and instrumentation Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 24/27] x86/int3: Avoid atomic instrumentation Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 25/27] lib/bsearch: Provide __always_inline variant Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 26/27] x86/int3: Inline bsearch() Peter Zijlstra
2020-02-21 13:34 ` [PATCH v4 27/27] x86/int3: Ensure that poke_int3_handler() is not sanitized Peter Zijlstra
2020-02-23 19:36   ` kbuild test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200221134215.149193474@infradead.org \
    --to=peterz@infradead.org \
    --cc=dan.carpenter@oracle.com \
    --cc=frederic@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=gustavo@embeddedor.com \
    --cc=jiangshanlai@gmail.com \
    --cc=joel@joelfernandes.org \
    --cc=josh@joshtriplett.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=maz@kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=pmladek@suse.com \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.