|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v9 09/10] x86: use / "support" UDB
With opcode D6h now firmly reserved as another #UD-raising one in 64-bit
mode, use that instead of the two-byte UD2 for bug frame marking.
While there also make the respective adjustment to the emulator.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
Should we also switch {svm,vmx}_init_hypercall_page()?
Furthermore x86_64/kexec_reloc.S also has two uses. Question is whether
"tailcall" is being open-coded there, or whether that's deliberately not
using the macro we have.
One of the table entries in stub_selftest() uses UD1, yet not in quite
an appropriate way: The 0x90 following it (presumably meant to be a NOP)
really is a ModR/M byte, requiring a displacement to follow. Wouldn't we
better adjust that (e.g. using 0xcc instead)?
---
v9: New.
--- a/xen/arch/x86/include/asm/bug.h
+++ b/xen/arch/x86/include/asm/bug.h
@@ -21,7 +21,7 @@
#ifndef __ASSEMBLY__
-#define BUG_INSTR "ud2"
+#define BUG_INSTR ".byte 0xd6" /* UDB */
#define BUG_ASM_CONST "c"
#else /* !__ASSEMBLY__ */
@@ -37,7 +37,7 @@
.error "Invalid BUGFRAME index"
.endif
- .L\@ud: ud2a
+ .L\@ud: .byte 0xd6 /* UDB */
.pushsection .rodata.str1, "aMS", @progbits, 1
.L\@s1: .asciz "\file_str"
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1256,7 +1256,7 @@ void asmlinkage do_trap(struct cpu_user_
void asmlinkage do_invalid_op(struct cpu_user_regs *regs)
{
- u8 bug_insn[2];
+ uint8_t bug_insn;
const void *eip = (const void *)regs->rip;
int id;
@@ -1268,8 +1268,8 @@ void asmlinkage do_invalid_op(struct cpu
}
if ( !is_active_kernel_text(regs->rip) ||
- copy_from_unsafe(bug_insn, eip, sizeof(bug_insn)) ||
- memcmp(bug_insn, "\xf\xb", sizeof(bug_insn)) )
+ copy_from_unsafe(&bug_insn, eip, sizeof(bug_insn)) ||
+ bug_insn != 0xd6 /* UDB */ )
goto die;
id = do_bug_frame(regs, regs->rip);
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -651,7 +651,7 @@ decode_onebyte(struct x86_emulate_state
case 0xce: /* into */
case 0xd4: /* aam */
case 0xd5: /* aad */
- case 0xd6: /* salc */
+ /* 0xd6 (salc) omitted here, for #UD to be raised in 64-bit mode. */
s->not_64bit = true;
break;
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -2470,9 +2470,17 @@ x86_emulate(
_regs.eflags |= even_parity(_regs.al) ? X86_EFLAGS_PF : 0;
break;
- case 0xd6: /* salc */
- _regs.al = (_regs.eflags & X86_EFLAGS_CF) ? 0xff : 0x00;
- break;
+ case 0xd6: /* salc / udb */
+ if ( !mode_64bit() )
+ {
+ _regs.al = (_regs.eflags & X86_EFLAGS_CF) ? 0xff : 0x00;
+ break;
+ }
+ fallthrough;
+ case X86EMUL_OPC(0x0f, 0x0b): /* ud2 */
+ case X86EMUL_OPC(0x0f, 0xb9): /* ud1 */
+ case X86EMUL_OPC(0x0f, 0xff): /* ud0 */
+ generate_exception(X86_EXC_UD);
case 0xd7: /* xlat */ {
unsigned long al;
@@ -3204,11 +3212,6 @@ x86_emulate(
goto done;
break;
- case X86EMUL_OPC(0x0f, 0x0b): /* ud2 */
- case X86EMUL_OPC(0x0f, 0xb9): /* ud1 */
- case X86EMUL_OPC(0x0f, 0xff): /* ud0 */
- generate_exception(X86_EXC_UD);
-
case X86EMUL_OPC(0x0f, 0x0d): /* GrpP (prefetch) */
case X86EMUL_OPC(0x0f, 0x18): /* Grp16 (prefetch/nop) */
case X86EMUL_OPC(0x0f, 0x19) ... X86EMUL_OPC(0x0f, 0x1f): /* nop */
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |