x86/debug: Use UD2 for WARN()

"Linux Kernel Mailing List" <[email protected]> Thu, 15 Feb 2018 01:31:43 +0000 (UTC)
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/3b3a371cc9bc980429baabe0a8e5f307f3d1f463
Commit:     3b3a371cc9bc980429baabe0a8e5f307f3d1f463
Parent:     2b5db66862b95532cb6cca8165ae6eb73633cf85
Refname:    refs/heads/master
Author:     Peter Zijlstra <[email protected]>
AuthorDate: Fri Feb 9 13:16:59 2018 +0100
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu Feb 15 01:15:50 2018 +0100

    x86/debug: Use UD2 for WARN()
    
    Since the Intel SDM added an ModR/M byte to UD0 and binutils followed
    that specification, we now cannot disassemble our kernel anymore.
    
    This now means Intel and AMD disagree on the encoding of UD0. And instead
    of playing games with additional bytes that are valid ModR/M and single
    byte instructions (0xd6 for instance), simply use UD2 for both WARN() and
    BUG().
    
    Requested-by: Linus Torvalds <[email protected]>
    Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
    Acked-by: Linus Torvalds <[email protected]>
    Cc: Andy Lutomirski <[email protected]>
    Cc: Arjan van de Ven <[email protected]>
    Cc: Borislav Petkov <[email protected]>
    Cc: Brian Gerst <[email protected]>
    Cc: Denys Vlasenko <[email protected]>
    Cc: H. Peter Anvin <[email protected]>
    Cc: Josh Poimboeuf <[email protected]>
    Cc: Peter Zijlstra <[email protected]>
    Cc: Thomas Gleixner <[email protected]>
    Link: http://lkml.kernel.org/r/[email protected]
    Signed-off-by: Ingo Molnar <[email protected]>
---
 arch/x86/include/asm/bug.h | 15 ++++++---------
 arch/x86/kernel/traps.c    |  2 +-
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index 71e6f4bf9161..6804d6642767 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -5,23 +5,20 @@
 #include <linux/stringify.h>
 
 /*
- * Since some emulators terminate on UD2, we cannot use it for WARN.
- * Since various instruction decoders disagree on the length of UD1,
- * we cannot use it either. So use UD0 for WARN.
+ * Despite that some emulators terminate on UD2, we use it for WARN().
  *
- * (binutils knows about "ud1" but {en,de}codes it as 2 bytes, whereas
- *  our kernel decoder thinks it takes a ModRM byte, which seems consistent
- *  with various things like the Intel SDM instruction encoding rules)
+ * Since various instruction decoders/specs disagree on the encoding of
+ * UD0/UD1.
  */
 
-#define ASM_UD0		".byte 0x0f, 0xff"
+#define ASM_UD0		".byte 0x0f, 0xff" /* + ModRM (for Intel) */
 #define ASM_UD1		".byte 0x0f, 0xb9" /* + ModRM */
 #define ASM_UD2		".byte 0x0f, 0x0b"
 
 #define INSN_UD0	0xff0f
 #define INSN_UD2	0x0b0f
 
-#define LEN_UD0		2
+#define LEN_UD2		2
 
 #ifdef CONFIG_GENERIC_BUG
 
@@ -79,7 +76,7 @@ do {								\
 
 #define __WARN_FLAGS(flags)					\
 do {								\
-	_BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags));		\
+	_BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags));		\
 	annotate_reachable();					\
 } while (0)
 
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 446c9ef8cfc3..3d9b2308e7fa 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -181,7 +181,7 @@ int fixup_bug(struct pt_regs *regs, int trapnr)
 		break;
 
 	case BUG_TRAP_TYPE_WARN:
-		regs->ip += LEN_UD0;
+		regs->ip += LEN_UD2;
 		return 1;
 	}
 
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html