]> xenbits.xensource.com Git - people/tklengyel/xen.git/commitdiff
x86/emul: Update emulation stubs to be CET-IBT compatible
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 1 Nov 2021 10:09:59 +0000 (10:09 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 23 Feb 2022 15:33:43 +0000 (15:33 +0000)
All indirect branches need to land on an endbr64 instruction.

For stub_selftests(), use endbr64 unconditionally for simplicity.  For ioport
and instruction emulation, add endbr64 conditionally.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/extable.c
xen/arch/x86/pv/emul-priv-op.c
xen/arch/x86/x86_emulate.c

index 4d1875585f9d997bbdd76e9bbb8408146895f9bb..4913c4a6dd5d10e0b0a1e1d1613f56d98aaa3101 100644 (file)
@@ -129,20 +129,22 @@ search_exception_table(const struct cpu_user_regs *regs)
 static int __init cf_check stub_selftest(void)
 {
     static const struct {
-        uint8_t opc[4];
+        uint8_t opc[8];
         uint64_t rax;
         union stub_exception_token res;
     } tests[] __initconst = {
-        { .opc = { 0x0f, 0xb9, 0xc3, 0xc3 }, /* ud1 */
+#define endbr64 0xf3, 0x0f, 0x1e, 0xfa
+        { .opc = { endbr64, 0x0f, 0xb9, 0xc3, 0xc3 }, /* ud1 */
           .res.fields.trapnr = TRAP_invalid_op },
-        { .opc = { 0x90, 0x02, 0x00, 0xc3 }, /* nop; add (%rax),%al */
+        { .opc = { endbr64, 0x90, 0x02, 0x00, 0xc3 }, /* nop; add (%rax),%al */
           .rax = 0x0123456789abcdef,
           .res.fields.trapnr = TRAP_gp_fault },
-        { .opc = { 0x02, 0x04, 0x04, 0xc3 }, /* add (%rsp,%rax),%al */
+        { .opc = { endbr64, 0x02, 0x04, 0x04, 0xc3 }, /* add (%rsp,%rax),%al */
           .rax = 0xfedcba9876543210,
           .res.fields.trapnr = TRAP_stack_error },
-        { .opc = { 0xcc, 0xc3, 0xc3, 0xc3 }, /* int3 */
+        { .opc = { endbr64, 0xcc, 0xc3, 0xc3, 0xc3 }, /* int3 */
           .res.fields.trapnr = TRAP_int3 },
+#undef endbr64
     };
     unsigned long addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2;
     unsigned int i;
index c46c072f93db2e88bac17c5c644080c1c0743ac0..22b10dec2a6ef5d0afcc3c87dc0d635c55100364 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <asm/amd.h>
 #include <asm/debugreg.h>
+#include <asm/endbr.h>
 #include <asm/hpet.h>
 #include <asm/hypercall.h>
 #include <asm/mc146818rtc.h>
@@ -111,6 +112,12 @@ static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
 
     p = ctxt->io_emul_stub;
 
+    if ( cpu_has_xen_ibt )
+    {
+        place_endbr64(p);
+        p += 4;
+    }
+
     APPEND_BUFF(prologue);
     APPEND_CALL(load_guest_gprs);
 
index 60191a94dc180fb7b5bcb0471f10b59b7f66a134..720740f29b847519421affb3efcc1c5e794a87c2 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/xstate.h>
 #include <asm/amd.h> /* cpu_has_amd_erratum() */
 #include <asm/debugreg.h>
+#include <asm/endbr.h>
 
 /* Avoid namespace pollution. */
 #undef cmpxchg
         cpu_has_amd_erratum(&current_cpu_data, AMD_ERRATUM_##nr)
 
 #define get_stub(stb) ({                                        \
+    void *ptr;                                                  \
     BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX_INST_LEN + 1);         \
     ASSERT(!(stb).ptr);                                         \
     (stb).addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2;      \
-    memset(((stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn)))) +  \
-           ((stb).addr & ~PAGE_MASK), 0xcc, STUB_BUF_SIZE / 2);        \
+    (stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn))) +    \
+        ((stb).addr & ~PAGE_MASK);                              \
+    ptr = memset((stb).ptr, 0xcc, STUB_BUF_SIZE / 2);           \
+    if ( cpu_has_xen_ibt )                                      \
+    {                                                           \
+        place_endbr64(ptr);                                     \
+        ptr += 4;                                               \
+    }                                                           \
+    ptr;                                                        \
 })
 #define put_stub(stb) ({                                   \
     if ( (stb).ptr )                                       \