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 v3 2/2] x86/traps: Dump instruction stream in show_execution_state()
Date: Thu, 11 Feb 2016 14:33:54 +0000	[thread overview]
Message-ID: <1455201234-19641-1-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1455187972-30566-2-git-send-email-andrew.cooper3@citrix.com>

For first pass triage of crashes, it is useful to have the instruction
stream present, especially now that Xen binary patches itself.

A sample output now looks like:

(XEN) ----[ Xen-4.7-unstable  x86_64  debug=y  Not tainted ]----
(XEN) CPU:    0
(XEN) RIP:    e008:[<ffff82d0801607e4>] default_idle+0x76/0x7b
(XEN) RFLAGS: 0000000000000246   CONTEXT: hypervisor
(XEN) rax: ffff82d080331030   rbx: ffff83007fce8000   rcx: 0000000000000000
(XEN) rdx: 0000000000000000   rsi: ffff82d080331b98   rdi: 0000000000000000
(XEN) rbp: ffff83007fcefef0   rsp: ffff83007fcefef0   r8:  ffff83007faf8118
(XEN) r9:  00000009983e89fd   r10: 00000009983e89fd   r11: 0000000000000246
(XEN) r12: ffff83007fd61000   r13: 00000000ffffffff   r14: ffff83007fad9000
(XEN) r15: ffff83007fae3000   cr0: 000000008005003b   cr4: 00000000000026e0
(XEN) cr3: 000000007fc9b000   cr2: 00007f70976b3fed
(XEN) ds: 0000   es: 0000   fs: 0000   gs: 0000   ss: e010   cs: e008
(XEN) Xen code around <ffff82d0801607e4> (default_idle+0x76/0x7b):
(XEN)  83 3c 10 00 75 04 fb f4 <eb> 01 fb 5d c3 55 48 89 e5 3b 3d 0d 50 12 00 72
(XEN) Xen stack trace from rsp=ffff83007fcefef0:
(XEN)    ffff83007fceff10 ffff82d080160e08 ffff82d08012c40a ffff83007faf9000
(XEN)    ffff83007fcefdd8 ffffffff81a01fd8 ffff88002f07d4c0 ffffffff81a01fd8
(XEN)    0000000000000000 ffffffff81a01e58 ffffffff81a01fd8 0000000000000246
(XEN)    00000000ffff0052 0000000000000000 0000000000000000 0000000000000000
(XEN)    ffffffff810013aa 0000000000000001 00000000deadbeef 00000000deadbeef
(XEN)    0000010000000000 ffffffff810013aa 000000000000e033 0000000000000246
(XEN)    ffffffff81a01e40 000000000000e02b 0000000000000000 0000000000000000
(XEN)    0000000000000000 0000000000000000 0000000000000000 ffff83007faf9000
(XEN)    0000000000000000 0000000000000000
(XEN) Xen call trace:
(XEN)    [<ffff82d0801607e4>] default_idle+0x76/0x7b
(XEN)    [<ffff82d080160e08>] idle_loop+0x51/0x6e
(XEN)

A sample with a partial access looks like:

(XEN) Xen code around <ffff8300ac0fe002> (ffff8300ac0fe002) [fault on access]:
(XEN)  -- -- -- -- -- -- 00 00 <00> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>

v3:
 * Read backwards from %rip, to get the instructions closer to %rip in the
   case that there is a fault somewhere on the access.  Use handrolled asm
   with custom fault handling.
v2:
 * Deal with %rip wrapping.  In such a case, insert dashes into printed line.
---
 xen/arch/x86/traps.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index ab7deee..26a5026 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -114,6 +114,74 @@ boolean_param("ler", opt_ler);
 #define stack_words_per_line 4
 #define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->rsp)
 
+static void show_code(const struct cpu_user_regs *regs)
+{
+    unsigned char insns_before[8] = {}, insns_after[16] = {};
+    unsigned int i, tmp, missing_before, missing_after;
+
+    if ( guest_mode(regs) )
+        return;
+
+    stac();
+
+    /*
+     * Copy forward from regs->rip.  In the case of a fault, %ecx contains the
+     * number of bytes remaining to copy.
+     */
+    asm volatile ("1: rep movsb; 2:"
+                  _ASM_EXTABLE(1b, 2b)
+                  : "=&c" (missing_after),
+                    "=&D" (tmp), "=&S" (tmp)
+                  : "0" (ARRAY_SIZE(insns_after)),
+                    "1" (insns_after),
+                    "2" (regs->rip));
+
+    /*
+     * Copy backwards from regs->rip - 1.  In the case of a fault, %ecx
+     * contains the number of bytes remaining to copy.
+     */
+    asm volatile ("std;"
+                  "1: rep movsb;"
+                  "2: cld;"
+                  _ASM_EXTABLE(1b, 2b)
+                  : "=&c" (missing_before),
+                    "=&D" (tmp), "=&S" (tmp)
+                  : "0" (ARRAY_SIZE(insns_before)),
+                    "1" (insns_before + ARRAY_SIZE(insns_before)),
+                    "2" (regs->rip - 1));
+    clac();
+
+    printk("Xen code around <%p> (%ps)%s:\n",
+           _p(regs->rip), _p(regs->rip),
+           (missing_before || missing_after) ? " [fault on access]" : "");
+
+    /* Print bytes from insns_before[]. */
+    for ( i = 0; i < ARRAY_SIZE(insns_before); ++i )
+    {
+        if ( i < missing_before )
+            printk(" --");
+        else
+            printk(" %02x", insns_before[i]);
+    }
+
+    /* Print the byte under %rip. */
+    if ( missing_after != ARRAY_SIZE(insns_after) )
+        printk(" <%02x>", insns_after[0]);
+    else
+        printk(" <-->");
+
+    /* Print bytes from insns_after[]. */
+    for ( i = 1; i < ARRAY_SIZE(insns_after); ++i )
+    {
+        if ( i < (ARRAY_SIZE(insns_after) - missing_after) )
+            printk(" %02x", insns_after[i]);
+        else
+            printk(" --");
+    }
+
+    printk("\n");
+}
+
 static void show_guest_stack(struct vcpu *v, const struct cpu_user_regs *regs)
 {
     int i;
@@ -420,6 +488,7 @@ void show_execution_state(const struct cpu_user_regs *regs)
     unsigned long flags = console_lock_recursive_irqsave();
 
     show_registers(regs);
+    show_code(regs);
     show_stack(regs);
 
     console_unlock_recursive_irqrestore(flags);
-- 
2.1.4

      parent reply	other threads:[~2016-02-11 14:33 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-11 10:52 [PATCH v2 1/2] x86/traps: Prevent interleaving of concurrent cpu state dumps Andrew Cooper
2016-02-11 10:52 ` [PATCH v2 2/2] x86/traps: Dump instruction stream in show_execution_state() Andrew Cooper
2016-02-11 11:16   ` Jan Beulich
2016-02-11 12:12     ` Andrew Cooper
2016-02-11 12:52       ` Jan Beulich
2016-02-11 13:41         ` Andrew Cooper
2016-02-11 13:55           ` Jan Beulich
2016-02-11 14:33   ` Andrew Cooper [this message]

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=1455201234-19641-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).