All of lore.kernel.org
 help / color / mirror / Atom feed
From: "tip-bot2 for Peter Zijlstra" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Andy Lutomirski <luto@kernel.org>, x86 <x86@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: [tip: x86/entry] x86/entry: Fix #UD vs WARN more
Date: Thu, 25 Jun 2020 11:53:32 -0000	[thread overview]
Message-ID: <159308601215.16989.11684885436197238827.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20200622114713.GE577403@hirez.programming.kicks-ass.net>

The following commit has been merged into the x86/entry branch of tip:

Commit-ID:     145a773aef83181d47ebab21bb33c89233aadb1e
Gitweb:        https://git.kernel.org/tip/145a773aef83181d47ebab21bb33c89233aadb1e
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Tue, 16 Jun 2020 13:28:36 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Thu, 25 Jun 2020 13:45:40 +02:00

x86/entry: Fix #UD vs WARN more

vmlinux.o: warning: objtool: exc_invalid_op()+0x47: call to probe_kernel_read() leaves .noinstr.text section

Since we use UD2 as a short-cut for 'CALL __WARN', treat it as such.
Have the bare exception handler do the report_bug() thing.

Fixes: 15a416e8aaa7 ("x86/entry: Treat BUG/WARN as NMI-like entries")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Andy Lutomirski <luto@kernel.org>
Link: https://lkml.kernel.org/r/20200622114713.GE577403@hirez.programming.kicks-ass.net
---
 arch/x86/kernel/traps.c | 72 +++++++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 34 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index a7d1570..1d9ea21 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -84,17 +84,16 @@ static inline void cond_local_irq_disable(struct pt_regs *regs)
 		local_irq_disable();
 }
 
-int is_valid_bugaddr(unsigned long addr)
+__always_inline int is_valid_bugaddr(unsigned long addr)
 {
-	unsigned short ud;
-
 	if (addr < TASK_SIZE_MAX)
 		return 0;
 
-	if (probe_kernel_address((unsigned short *)addr, ud))
-		return 0;
-
-	return ud == INSN_UD0 || ud == INSN_UD2;
+	/*
+	 * We got #UD, if the text isn't readable we'd have gotten
+	 * a different exception.
+	 */
+	return *(unsigned short *)addr == INSN_UD2;
 }
 
 static nokprobe_inline int
@@ -216,40 +215,45 @@ static inline void handle_invalid_op(struct pt_regs *regs)
 		      ILL_ILLOPN, error_get_trap_addr(regs));
 }
 
-DEFINE_IDTENTRY_RAW(exc_invalid_op)
+static noinstr bool handle_bug(struct pt_regs *regs)
 {
-	bool rcu_exit;
+	bool handled = false;
+
+	if (!is_valid_bugaddr(regs->ip))
+		return handled;
 
 	/*
-	 * Handle BUG/WARN like NMIs instead of like normal idtentries:
-	 * if we bugged/warned in a bad RCU context, for example, the last
-	 * thing we want is to BUG/WARN again in the idtentry code, ad
-	 * infinitum.
+	 * All lies, just get the WARN/BUG out.
 	 */
-	if (!user_mode(regs) && is_valid_bugaddr(regs->ip)) {
-		enum bug_trap_type type;
+	instrumentation_begin();
+	/*
+	 * Since we're emulating a CALL with exceptions, restore the interrupt
+	 * state to what it was at the exception site.
+	 */
+	if (regs->flags & X86_EFLAGS_IF)
+		raw_local_irq_enable();
+	if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) {
+		regs->ip += LEN_UD2;
+		handled = true;
+	}
+	if (regs->flags & X86_EFLAGS_IF)
+		raw_local_irq_disable();
+	instrumentation_end();
 
-		nmi_enter();
-		instrumentation_begin();
-		trace_hardirqs_off_finish();
-		type = report_bug(regs->ip, regs);
-		if (regs->flags & X86_EFLAGS_IF)
-			trace_hardirqs_on_prepare();
-		instrumentation_end();
-		nmi_exit();
+	return handled;
+}
 
-		if (type == BUG_TRAP_TYPE_WARN) {
-			/* Skip the ud2. */
-			regs->ip += LEN_UD2;
-			return;
-		}
+DEFINE_IDTENTRY_RAW(exc_invalid_op)
+{
+	bool rcu_exit;
 
-		/*
-		 * Else, if this was a BUG and report_bug returns or if this
-		 * was just a normal #UD, we want to continue onward and
-		 * crash.
-		 */
-	}
+	/*
+	 * We use UD2 as a short encoding for 'CALL __WARN', as such
+	 * handle it before exception entry to avoid recursive WARN
+	 * in case exception entry is the one triggering WARNs.
+	 */
+	if (!user_mode(regs) && handle_bug(regs))
+		return;
 
 	rcu_exit = idtentry_enter_cond_rcu(regs);
 	instrumentation_begin();

  parent reply	other threads:[~2020-06-25 11:54 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-18 14:44 [PATCH 0/7] x86/entry: noinstr fixes Peter Zijlstra
2020-06-18 14:44 ` [PATCH 1/7] x86/entry: Fix #UD vs WARN more Peter Zijlstra
2020-06-18 14:57   ` Andy Lutomirski
2020-06-18 15:50     ` Peter Zijlstra
2020-06-18 18:36       ` Andy Lutomirski
2020-06-18 19:02         ` Peter Zijlstra
2020-06-18 19:29           ` Andy Lutomirski
2020-06-18 21:18             ` Peter Zijlstra
2020-06-22 11:47               ` Peter Zijlstra
2020-06-24 22:37                 ` Andy Lutomirski
2020-06-25 11:53                 ` tip-bot2 for Peter Zijlstra [this message]
2020-06-18 14:44 ` [PATCH 2/7] objtool: Dont consider vmlinux a C-file Peter Zijlstra
2020-06-25 11:53   ` [tip: x86/entry] objtool: Don't " tip-bot2 for Peter Zijlstra
2020-06-18 14:44 ` [PATCH 3/7] x86/entry: Fixup bad_iret vs noinstr Peter Zijlstra
2020-06-18 15:13   ` Marco Elver
2020-06-25 11:53   ` [tip: x86/entry] " tip-bot2 for Peter Zijlstra
2020-06-18 14:44 ` [PATCH 4/7] x86/entry: Increase entry_stack size to a full page Peter Zijlstra
2020-06-18 15:06   ` Marco Elver
2020-06-19  3:10   ` Lai Jiangshan
2020-06-25 11:53   ` [tip: x86/entry] " tip-bot2 for Peter Zijlstra
2020-06-18 14:44 ` [PATCH 5/7] objtool: Clean up elf_write() condition Peter Zijlstra
2020-06-18 14:44 ` [PATCH 6/7] objtool: Provide elf_write_{insn,reloc}() Peter Zijlstra
2020-06-18 14:44 ` [PATCH 7/7] objtool: Fix noinstr vs KCOV Peter Zijlstra

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=159308601215.16989.11684885436197238827.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=peterz@infradead.org \
    --cc=x86@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.