xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
	Jan Beulich <JBeulich@suse.com>
Subject: [PATCH v2] x86/emul: Poision the stubs with debug traps
Date: Mon, 20 Mar 2017 10:58:02 +0000	[thread overview]
Message-ID: <1490007482-20386-1-git-send-email-andrew.cooper3@citrix.com> (raw)

...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@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>

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@lists.xen.org
https://lists.xen.org/xen-devel

             reply	other threads:[~2017-03-20 10:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-20 10:58 Andrew Cooper [this message]
2017-03-20 11:50 ` [PATCH v2] x86/emul: Poision the stubs with debug traps Jan Beulich
2017-03-30 11:56   ` Andrew Cooper
2017-03-30 12:08     ` Jan Beulich
2017-03-30 17:09       ` Andrew Cooper
2017-03-31  7:31         ` Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1490007482-20386-1-git-send-email-andrew.cooper3@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).