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

Re: [Minios-devel] [UNIKRAFT PATCH 06/17] plat/common: Common x86 tracing functions



On 27.03.2018 14:29, Costin Lupu wrote:
Current changes introduce common x86 tracing functions (stack trace, register
dumps and memory dumps) which are moved from plat/xen. The interface should be
the same for all platforms and architectures.


This is a good intermediate step. In longer term most of these functions here should be part of the official ukarch and ukplat API. libukdebug should then the one that implements high-level logic of register dumps and stack walks on top. This way we avoid code duplication and get leaner platform libraries. However, this is another patch series. So, I am okay with this for now.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
  plat/common/include/trace.h | 48 ++++++++++++++++++++++++
  plat/common/x86/trace.c     | 90 +++++++++++++++++++++++++++++++++++++++++++++
  plat/xen/Makefile.uk        |  1 +
  plat/xen/x86/traps.c        | 70 +----------------------------------
  4 files changed, 141 insertions(+), 68 deletions(-)
  create mode 100644 plat/common/include/trace.h
  create mode 100644 plat/common/x86/trace.c

diff --git a/plat/common/include/trace.h b/plat/common/include/trace.h
new file mode 100644
index 0000000..a423153
--- /dev/null
+++ b/plat/common/include/trace.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+#ifndef __PLAT_CMN_TRACE_H__
+#define __PLAT_CMN_TRACE_H__
+
+#ifdef __X86_64__
+#include <x86/regs.h> /* TODO include a generic header */
+#else
+#error "Create regs.h for current architecture"
+#endif
+
+void dump_regs(struct __regs *regs);
+void dump_mem(unsigned long addr);
+void stack_walk(void);
+void stack_walk_for_frame(unsigned long frame_base);
+
+#endif /* __PLAT_CMN_TRACE_H__ */
diff --git a/plat/common/x86/trace.c b/plat/common/x86/trace.c
new file mode 100644
index 0000000..2962f3a
--- /dev/null
+++ b/plat/common/x86/trace.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+
+#include <trace.h>
+#include <uk/print.h>
+
+#define PAGE_SIZE 4096 /* TODO take this from another header */
+
+
+void dump_regs(struct __regs *regs)
+{
+       uk_printk("RIP: %016lx CS: %04lx\n", regs->rip, regs->cs & 0xffff);
+       uk_printk("RSP: %016lx SS: %04lx EFLAGS: %08lx\n",
+                       regs->rsp, regs->ss, regs->eflags);
+       uk_printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
+                       regs->rax, regs->rbx, regs->rcx);
+       uk_printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
+                       regs->rdx, regs->rsi, regs->rdi);
+       uk_printk("RBP: %016lx R08: %016lx R09: %016lx\n",
+                       regs->rbp, regs->r8, regs->r9);
+       uk_printk("R10: %016lx R11: %016lx R12: %016lx\n",
+                       regs->r10, regs->r11, regs->r12);
+       uk_printk("R13: %016lx R14: %016lx R15: %016lx\n",
+                       regs->r13, regs->r14, regs->r15);
+}

All prints should happen with uk_printd() instead of uk_printk(). Since the code in this file was just moved now, we fix this when getting an official API as I mentioned earlier. Can you add an TODO comment?

+
+void dump_mem(unsigned long addr)
+{
+       unsigned long i;
+
+       if (addr < PAGE_SIZE)
+               return;
+
+       for (i = ((addr) - 16) & ~15; i < (((addr) + 48) & ~15); i++) {
+               if (!(i % 16))
+                       uk_printk("\n%lx:", i);
+               uk_printk(" %02x", *(unsigned char *) i);
+       }
+       uk_printk("\n");
+}

This is a candidate that should be replaced later by uk_hexdump() [libukdebug]. Same here, can you add an TODO comment?

+
+void stack_walk(void)
+{
+       unsigned long bp;
+
+       asm("movq %%rbp, %0" : "=r"(bp));
+
+       stack_walk_for_frame(bp);
+}
+
+void stack_walk_for_frame(unsigned long frame_base)
+{
+       unsigned long *frame = (void *) frame_base;
+
+       uk_printk("base is %#lx ", frame_base);
+       uk_printk("caller is %#lx\n", frame[1]);
+       if (frame[0])
+               stack_walk_for_frame(frame[0]);
+}
diff --git a/plat/xen/Makefile.uk b/plat/xen/Makefile.uk
index 220c8d9..49c4352 100644
--- a/plat/xen/Makefile.uk
+++ b/plat/xen/Makefile.uk
@@ -29,6 +29,7 @@ LIBXENPLAT_SRCS-y              += 
$(LIBXENPLAT_BASE)/hypervisor.c
  LIBXENPLAT_SRCS-y              += $(LIBXENPLAT_BASE)/memory.c
ifneq (,$(filter x86_32 x86_64,$(UK_ARCH)))
+LIBXENPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/trace.c|common
  LIBXENPLAT_SRCS-y              += $(LIBXENPLAT_BASE)/x86/setup.c
  LIBXENPLAT_SRCS-y              += $(LIBXENPLAT_BASE)/x86/traps.c
  LIBXENPLAT_SRCS-$(ARCH_X86_32) += $(LIBXENPLAT_BASE)/x86/entry32.S
diff --git a/plat/xen/x86/traps.c b/plat/xen/x86/traps.c
index 7057839..da3ca9a 100644
--- a/plat/xen/x86/traps.c
+++ b/plat/xen/x86/traps.c
@@ -54,36 +54,6 @@ void machine_check(void);
        for (;;) {                                                             \
        }
-void dump_regs(struct __regs *regs)
-{
-// uk_printk("Thread: %s\n", current ? current->name : "*NONE*");
-#ifdef __X86_64__
-       uk_printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
-       uk_printk("\nRSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
-                 regs->eflags);
-       uk_printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", regs->rax, regs->rbx,
-                 regs->rcx);
-       uk_printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", regs->rdx, regs->rsi,
-                 regs->rdi);
-       uk_printk("RBP: %016lx R08: %016lx R09: %016lx\n", regs->rbp, regs->r8,
-                 regs->r9);
-       uk_printk("R10: %016lx R11: %016lx R12: %016lx\n", regs->r10, regs->r11,
-                 regs->r12);
-       uk_printk("R13: %016lx R14: %016lx R15: %016lx\n", regs->r13, regs->r14,
-                 regs->r15);
-#else
-       uk_printk("EIP: %lx, EFLAGS %lx.\n", regs->eip, regs->eflags);
-       uk_printk("EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->ebx, regs->ecx,
-                 regs->edx);
-       uk_printk("ESI: %08lx EDI: %08lx EBP: %08lx EAX: %08lx\n", regs->esi,
-                 regs->edi, regs->ebp, regs->eax);
-       uk_printk("DS: %04x ES: %04x orig_eax: %08lx, eip: %08lx\n", regs->xds,
-                 regs->xes, regs->orig_eax, regs->eip);
-       uk_printk("CS: %04x EFLAGS: %08lx esp: %08lx ss: %04x\n", regs->xcs,
-                 regs->eflags, regs->esp, regs->xss);
-#endif
-}
-
  static void do_trap(int trapnr, char *str, struct __regs *regs,
                    unsigned long error_code)
  {
@@ -118,42 +88,6 @@ DO_ERROR(12, "stack segment", stack_segment)
  DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
  DO_ERROR(18, "machine check", machine_check)
-static void do_stack_walk(unsigned long frame_base)
-{
-       unsigned long *frame = (void *)frame_base;
-
-       uk_printk("base is %#lx ", frame_base);
-       uk_printk("caller is %#lx\n", frame[1]);
-       if (frame[0])
-               do_stack_walk(frame[0]);
-}
-
-void stack_walk(void)
-{
-       unsigned long bp;
-#ifdef __x86_64__
-       asm("movq %%rbp, %0" : "=r"(bp));
-#else
-       asm("movl %%ebp, %0" : "=r"(bp));
-#endif
-       do_stack_walk(bp);
-}
-
-static void dump_mem(unsigned long addr)
-{
-       unsigned long i;
-
-       if (addr < PAGE_SIZE)
-               return;
-
-       for (i = ((addr)-16) & ~15; i < (((addr) + 48) & ~15); i++) {
-               if (!(i % 16))
-                       uk_printk("\n%lx:", i);
-               uk_printk(" %02x", *(unsigned char *)i);
-       }
-       uk_printk("\n");
-}
-
  static int handling_pg_fault;
void do_page_fault(struct __regs *regs, unsigned long error_code)
@@ -182,7 +116,7 @@ void do_page_fault(struct __regs *regs, unsigned long 
error_code)
dump_regs(regs);
  #ifdef __X86_64__
-       do_stack_walk(regs->rbp);
+       stack_walk_for_frame(regs->rbp);
        dump_mem(regs->rsp);
        dump_mem(regs->rbp);
        dump_mem(regs->rip);
@@ -207,7 +141,7 @@ void do_general_protection(struct __regs *regs, long 
error_code)
  #endif
        dump_regs(regs);
  #ifdef __X86_64__
-       do_stack_walk(regs->rbp);
+       stack_walk_for_frame(regs->rbp);
        dump_mem(regs->rsp);
        dump_mem(regs->rbp);
        dump_mem(regs->rip);


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

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