[PATCH v10] x86: use / "support" UDB

Jan Beulich posted 1 patch 4 days, 8 hours ago
Failed in applying to current master (apply log)
[PATCH v10] x86: use / "support" UDB
Posted by Jan Beulich 4 days, 8 hours ago
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 a minor adjustment to the emulator.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
One of the table entries in stub_selftest() uses UD1, yet in not 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)?
---
v10: Shrink the actual emulator change to just a comment adjustment.
     Extend .byte directive commentary.
v9: New.

--- a/xen/arch/x86/include/asm/bug.h
+++ b/xen/arch/x86/include/asm/bug.h
@@ -21,7 +21,7 @@
 
 #ifndef __ASSEMBLER__
 
-#define BUG_INSTR       "ud2"
+#define BUG_INSTR       ".byte 0xd6" /* UDB, requiring gas 2.46 */
 #define BUG_ASM_CONST   "c"
 
 #else  /* !__ASSEMBLER__ */
@@ -37,7 +37,7 @@
         .error "Invalid BUGFRAME index"
     .endif
 
-    .L\@ud: ud2a
+    .L\@ud: .byte 0xd6 /* UDB, requiring gas 2.46 */
 
     .pushsection .rodata.str1, "aMS", @progbits, 1
          .L\@s1: .asciz "\file_str"
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1338,7 +1338,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;
 
@@ -1350,8 +1350,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 */
+    case 0xd6: /* salc / udb */
         s->not_64bit = true;
         break;
Re: [PATCH v10] x86: use / "support" UDB
Posted by Andrew Cooper 4 days, 2 hours ago
On 08/04/2026 1:12 pm, Jan Beulich wrote:
> 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 a minor adjustment to the emulator.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

For the patch itself, Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>

> ---
> One of the table entries in stub_selftest() uses UD1, yet in not 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)?

That looks too much like breakpoint padding as opposed to nop padding.

What about:

diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c
index a9b6c6b904f5..24440ccd03e3 100644
--- a/xen/arch/x86/extable.c
+++ b/xen/arch/x86/extable.c
@@ -157,7 +157,7 @@ int __init cf_check stub_selftest(void)
         union stub_exception_token res;
     } tests[] __initconst = {
 #define endbr64 0xf3, 0x0f, 0x1e, 0xfa
-        { .opc = { endbr64, 0x0f, 0xb9, 0x90 }, /* ud1 */
+        { .opc = { endbr64, 0x0f, 0xb9, 0x00 }, /* ud1 (%rax),%eax */
           .res.fields.trapnr = X86_EXC_UD },
         { .opc = { endbr64, 0x90, 0x02, 0x00 }, /* nop; add (%rax),%al */
           .rax = 0x0123456789abcdef,

which also brings it in line with the adjacent example?

~Andrew

Re: [PATCH v10] x86: use / "support" UDB
Posted by Jan Beulich 3 days, 15 hours ago
On 08.04.2026 20:04, Andrew Cooper wrote:
> On 08/04/2026 1:12 pm, Jan Beulich wrote:
>> 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 a minor adjustment to the emulator.
>>
>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> 
> For the patch itself, Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>

Thanks.

>> ---
>> One of the table entries in stub_selftest() uses UD1, yet in not 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)?
> 
> That looks too much like breakpoint padding as opposed to nop padding.
> 
> What about:
> 
> diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c
> index a9b6c6b904f5..24440ccd03e3 100644
> --- a/xen/arch/x86/extable.c
> +++ b/xen/arch/x86/extable.c
> @@ -157,7 +157,7 @@ int __init cf_check stub_selftest(void)
>          union stub_exception_token res;
>      } tests[] __initconst = {
>  #define endbr64 0xf3, 0x0f, 0x1e, 0xfa
> -        { .opc = { endbr64, 0x0f, 0xb9, 0x90 }, /* ud1 */
> +        { .opc = { endbr64, 0x0f, 0xb9, 0x00 }, /* ud1 (%rax),%eax */
>            .res.fields.trapnr = X86_EXC_UD },
>          { .opc = { endbr64, 0x90, 0x02, 0x00 }, /* nop; add (%rax),%al */
>            .rax = 0x0123456789abcdef,
> 
> which also brings it in line with the adjacent example?

That's also okay, sure.

Jan