From patchwork Thu Feb 11 14:33:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 8280891 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C2BA1BEEE5 for ; Thu, 11 Feb 2016 14:37:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BEB102039E for ; Thu, 11 Feb 2016 14:37:08 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 995E52009C for ; Thu, 11 Feb 2016 14:37:07 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aTsJl-0005lX-PX; Thu, 11 Feb 2016 14:34:01 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aTsJj-0005lS-LG for xen-devel@lists.xen.org; Thu, 11 Feb 2016 14:34:00 +0000 Received: from [85.158.137.68] by server-6.bemta-3.messagelabs.com id E8/E6-08479-6DB9CB65; Thu, 11 Feb 2016 14:33:58 +0000 X-Env-Sender: prvs=84296f867=Andrew.Cooper3@citrix.com X-Msg-Ref: server-12.tower-31.messagelabs.com!1455201236!21715296!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 22385 invoked from network); 11 Feb 2016 14:33:57 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-12.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 11 Feb 2016 14:33:57 -0000 X-IronPort-AV: E=Sophos;i="5.22,431,1449532800"; d="scan'208";a="337559011" From: Andrew Cooper To: Xen-devel Date: Thu, 11 Feb 2016 14:33:54 +0000 Message-ID: <1455201234-19641-1-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455187972-30566-2-git-send-email-andrew.cooper3@citrix.com> References: <1455187972-30566-2-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-DLP: MIA1 Cc: Andrew Cooper , Jan Beulich Subject: [Xen-devel] [PATCH v3 2/2] x86/traps: Dump instruction stream in show_execution_state() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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:[] 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 (default_idle+0x76/0x7b): (XEN) 83 3c 10 00 75 04 fb f4 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) [] default_idle+0x76/0x7b (XEN) [] idle_loop+0x51/0x6e (XEN) A sample with a partial access looks like: (XEN) Xen code around (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 --- CC: Jan Beulich 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);