[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2] x86/emul: Poision the stubs with debug traps



...rather than leaving fragments of old instructions in place.  This reduces
the chances of something going further-wrong (as the debug trap will be caught
and terminate the guest) in a cascade-failure where we end up executing the
instruction fragments.

Before:
    (XEN) d2v0 exception 6 (ec=0000) in emulation stub (line 6239)
    (XEN) d2v0 stub: c4 e1 44 77 c3 80 d0 82 ff ff ff d1 90 ec 90

After:
    (XEN) d3v0 exception 6 (ec=0000) in emulation stub (line 6239)
    (XEN) d3v0 stub: c4 e1 44 77 c3 cc cc cc cc cc cc cc cc cc cc

To make this work, the int3 handler needs to be extended to attempt recovery
rather than simply returning back to Xen context.  This is a good general
precaution anyway, as nothing good will happen from letting Xen blindly
execute over 0xcc's.

Extend the selftests to include int3, and add an extra printk indicating the
start of the recovery selftests, to avoid leaving two otherwise-spurious
faults visible in the log.

    (XEN) build-id: f0a0617cdb725551d03689c23bc59f34d329c182
    (XEN) Running stub recovery selftests...
    (XEN) traps.c:3463: GPF (0000): ffff82d0bffff041 [ffff82d0bffff041] -> 
ffff82d08025789a
    (XEN) traps.c:813: Trap 12: ffff82d0bffff040 [ffff82d0bffff040] -> 
ffff82d08025789a
    (XEN) ACPI sleep modes: S3

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>

v2:
 * Add selftest.  Recover from int3.
---
 xen/arch/x86/extable.c     |  4 ++++
 xen/arch/x86/traps.c       | 18 +++++++++++++++---
 xen/arch/x86/x86_emulate.c |  4 ++--
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c
index 03af2c9..6fffe05 100644
--- a/xen/arch/x86/extable.c
+++ b/xen/arch/x86/extable.c
@@ -140,10 +140,14 @@ static int __init stub_selftest(void)
         { .opc = { 0x02, 0x04, 0x04, 0xc3 }, /* add (%rsp,%rax),%al */
           .rax = 0xfedcba9876543210,
           .res.fields.trapnr = TRAP_stack_error },
+        { .opc = { 0xcc, 0xc3, 0xc3, 0xc3 }, /* int3 */
+          .res.fields.trapnr = TRAP_int3 },
     };
     unsigned long addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2;
     unsigned int i;
 
+    printk("Running stub recovery selftests...\n");
+
     for ( i = 0; i < ARRAY_SIZE(tests); ++i )
     {
         uint8_t *ptr = map_domain_page(_mfn(this_cpu(stubs.mfn))) +
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 0d54baf..fd5fb56 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1206,9 +1206,21 @@ void do_int3(struct cpu_user_regs *regs)
 
     if ( !guest_mode(regs) )
     {
-        debugger_trap_fatal(TRAP_int3, regs);
-        return;
-    } 
+        unsigned long fixup;
+
+        if ( (fixup = search_exception_table(regs)) != 0 )
+        {
+            this_cpu(last_extable_addr) = regs->rip;
+            regs->rip = fixup;
+            return;
+        }
+
+        if ( debugger_trap_fatal(TRAP_int3, regs) )
+            return;
+
+        show_execution_state(regs);
+        panic("FATAL TRAP: vector = %d (int3)", TRAP_int3);
+    }
 
     do_guest_trap(TRAP_int3, regs);
 }
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index 51df340..cc334ca 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -30,8 +30,8 @@
     BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX_INST_LEN + 1);         \
     ASSERT(!(stb).ptr);                                         \
     (stb).addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2;      \
-    ((stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn)))) +  \
-        ((stb).addr & ~PAGE_MASK);                              \
+    memset(((stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn)))) +  \
+           ((stb).addr & ~PAGE_MASK), 0xcc, STUB_BUF_SIZE / 2);        \
 })
 #define put_stub(stb) ({                                   \
     if ( (stb).ptr )                                       \
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.