All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: xen-devel@lists.xenproject.org, ross.lagerwall@citrix.com,
	mpohlack@amazon.com, andrew.cooper3@citrix.com,
	stefano.stabellini@citrix.com, jbeulich@suse.com,
	ian.jackson@eu.citrix.com, ian.campbell@citrix.com,
	wei.liu2@citrix.com, sasha.levin@oracle.com
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: [PATCH v2 11/13] xsplice: Add support for bug frames. (v2)
Date: Thu, 14 Jan 2016 16:47:09 -0500	[thread overview]
Message-ID: <1452808031-706-12-git-send-email-konrad.wilk@oracle.com> (raw)
In-Reply-To: <1452808031-706-1-git-send-email-konrad.wilk@oracle.com>

From: Ross Lagerwall <ross.lagerwall@citrix.com>

Add support for handling bug frames contained with xsplice modules. If a
trap occurs search either the kernel bug table or an applied payload's
bug table depending on the instruction pointer.

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
v2:- s/module/payload/
   - add build time check in case amount of bug frames expands.
   - add define for the number of bug-frames.
---
 xen/arch/x86/traps.c      |  30 ++++++++-----
 xen/common/symbols.c      |   7 +++
 xen/common/xsplice.c      | 109 +++++++++++++++++++++++++++++++++++++++++-----
 xen/include/asm-arm/bug.h |   2 +
 xen/include/asm-x86/bug.h |   2 +
 xen/include/xen/kernel.h  |   1 +
 xen/include/xen/xsplice.h |  15 +++++++
 7 files changed, 145 insertions(+), 21 deletions(-)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index e105b95..6e80607 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -48,6 +48,7 @@
 #include <xen/kexec.h>
 #include <xen/trace.h>
 #include <xen/paging.h>
+#include <xen/xsplice.h>
 #include <xen/watchdog.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1080,20 +1081,29 @@ void do_invalid_op(struct cpu_user_regs *regs)
         return;
     }
 
-    if ( !is_active_kernel_text(regs->eip) ||
+    if ( !is_active_text(regs->eip) ||
          __copy_from_user(bug_insn, eip, sizeof(bug_insn)) ||
          memcmp(bug_insn, "\xf\xb", sizeof(bug_insn)) )
         goto die;
 
-    for ( bug = __start_bug_frames, id = 0; stop_frames[id]; ++bug )
+    if ( likely(is_active_kernel_text(regs->eip)) )
     {
-        while ( unlikely(bug == stop_frames[id]) )
-            ++id;
-        if ( bug_loc(bug) == eip )
-            break;
+        for ( bug = __start_bug_frames, id = 0; stop_frames[id]; ++bug )
+        {
+            while ( unlikely(bug == stop_frames[id]) )
+                ++id;
+            if ( bug_loc(bug) == eip )
+                break;
+        }
+        if ( !stop_frames[id] )
+            goto die;
+    }
+    else
+    {
+        bug = xsplice_find_bug(eip, &id);
+        if ( !bug )
+            goto die;
     }
-    if ( !stop_frames[id] )
-        goto die;
 
     eip += sizeof(bug_insn);
     if ( id == BUGFRAME_run_fn )
@@ -1107,7 +1117,7 @@ void do_invalid_op(struct cpu_user_regs *regs)
 
     /* WARN, BUG or ASSERT: decode the filename pointer and line number. */
     filename = bug_ptr(bug);
-    if ( !is_kernel(filename) )
+    if ( !is_kernel(filename) && !is_module(filename) )
         goto die;
     fixup = strlen(filename);
     if ( fixup > 50 )
@@ -1134,7 +1144,7 @@ void do_invalid_op(struct cpu_user_regs *regs)
     case BUGFRAME_assert:
         /* ASSERT: decode the predicate string pointer. */
         predicate = bug_msg(bug);
-        if ( !is_kernel(predicate) )
+        if ( !is_kernel(predicate) && !is_module(predicate) )
             predicate = "<unknown>";
 
         printk("Assertion '%s' failed at %s%s:%d\n",
diff --git a/xen/common/symbols.c b/xen/common/symbols.c
index a59c59d..bf5623f 100644
--- a/xen/common/symbols.c
+++ b/xen/common/symbols.c
@@ -17,6 +17,7 @@
 #include <xen/lib.h>
 #include <xen/string.h>
 #include <xen/spinlock.h>
+#include <xen/xsplice.h>
 #include <public/platform.h>
 #include <xen/guest_access.h>
 
@@ -101,6 +102,12 @@ bool_t is_active_kernel_text(unsigned long addr)
             (system_state < SYS_STATE_active && is_kernel_inittext(addr)));
 }
 
+bool_t is_active_text(unsigned long addr)
+{
+    return is_active_kernel_text(addr) ||
+           is_active_module_text(addr);
+}
+
 const char *symbols_lookup(unsigned long addr,
                            unsigned long *symbolsize,
                            unsigned long *offset,
diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c
index 5abeb28..02cb4a8 100644
--- a/xen/common/xsplice.c
+++ b/xen/common/xsplice.c
@@ -43,7 +43,10 @@ struct payload {
     struct list_head applied_list;       /* Linked to 'applied_list'. */
     struct xsplice_patch_func *funcs;    /* The array of functions to patch. */
     unsigned int nfuncs;                 /* Nr of functions to patch. */
-
+    size_t core_size;                    /* Only .text size. */
+    size_t core_text_size;               /* Everything else - .data,.rodata, etc. */
+    struct bug_frame *start_bug_frames[BUGFRAME_NR]; /* .bug.frame patching. */
+    struct bug_frame *stop_bug_frames[BUGFRAME_NR];
     char name[XEN_XSPLICE_NAME_SIZE + 1];/* Name of it. */
 };
 
@@ -544,26 +547,27 @@ static void free_payload_data(struct payload *payload)
     payload->payload_pages = 0;
 }
 
-static void calc_section(struct xsplice_elf_sec *sec, size_t *core_size)
+static void calc_section(struct xsplice_elf_sec *sec, size_t *size)
 {
-    size_t align_size = ROUNDUP(*core_size, sec->sec->sh_addralign);
+    size_t align_size = ROUNDUP(*size, sec->sec->sh_addralign);
     sec->sec->sh_entsize = align_size;
-    *core_size = sec->sec->sh_size + align_size;
+    *size = sec->sec->sh_size + align_size;
 }
 
 static int move_payload(struct payload *payload, struct xsplice_elf *elf)
 {
     uint8_t *buf;
     unsigned int i;
-    size_t core_size = 0;
+    size_t size = 0;
 
     /* Compute text regions */
     for ( i = 0; i < elf->hdr->e_shnum; i++ )
     {
         if ( (elf->sec[i].sec->sh_flags & (SHF_ALLOC|SHF_EXECINSTR)) ==
              (SHF_ALLOC|SHF_EXECINSTR) )
-            calc_section(&elf->sec[i], &core_size);
+            calc_section(&elf->sec[i], &size);
     }
+    payload->core_text_size = size;
 
     /* Compute rw data */
     for ( i = 0; i < elf->hdr->e_shnum; i++ )
@@ -571,7 +575,7 @@ static int move_payload(struct payload *payload, struct xsplice_elf *elf)
         if ( (elf->sec[i].sec->sh_flags & SHF_ALLOC) &&
              !(elf->sec[i].sec->sh_flags & SHF_EXECINSTR) &&
              (elf->sec[i].sec->sh_flags & SHF_WRITE) )
-            calc_section(&elf->sec[i], &core_size);
+            calc_section(&elf->sec[i], &size);
     }
 
     /* Compute ro data */
@@ -580,16 +584,17 @@ static int move_payload(struct payload *payload, struct xsplice_elf *elf)
         if ( (elf->sec[i].sec->sh_flags & SHF_ALLOC) &&
              !(elf->sec[i].sec->sh_flags & SHF_EXECINSTR) &&
              !(elf->sec[i].sec->sh_flags & SHF_WRITE) )
-            calc_section(&elf->sec[i], &core_size);
+            calc_section(&elf->sec[i], &size);
     }
+    payload->core_size = size;
 
-    buf = alloc_payload(core_size);
+    buf = alloc_payload(size);
     if ( !buf ) {
         printk(XENLOG_ERR "%s: Could not allocate memory for module\n",
                elf->name);
         return -ENOMEM;
     }
-    memset(buf, 0, core_size);
+    memset(buf, 0, size);
 
     for ( i = 0; i < elf->hdr->e_shnum; i++ )
     {
@@ -604,7 +609,7 @@ static int move_payload(struct payload *payload, struct xsplice_elf *elf)
     }
 
     payload->payload_address = buf;
-    payload->payload_pages = PFN_UP(core_size);
+    payload->payload_pages = PFN_UP(size);
 
     return 0;
 }
@@ -647,6 +652,22 @@ static int find_special_sections(struct payload *payload,
             if ( f->pad[j] )
                 return -EINVAL;
     }
+    for ( i = 0; i < BUGFRAME_NR; i++ )
+    {
+        char str[14];
+
+        snprintf(str, sizeof str, ".bug_frames.%d", i);
+        sec = xsplice_elf_sec_by_name(elf, str);
+        if ( !sec )
+            continue;
+
+        if ( ( !sec->sec->sh_size ) ||
+             ( sec->sec->sh_size % sizeof (struct bug_frame) ) )
+            return -EINVAL;
+
+        payload->start_bug_frames[i] = (struct bug_frame *)sec->load_addr;
+        payload->stop_bug_frames[i] = (struct bug_frame *)(sec->load_addr + sec->sec->sh_size);
+    }
     return 0;
 }
 
@@ -942,6 +963,72 @@ void do_xsplice(void)
     }
 }
 
+
+/*
+ * Functions for handling special sections.
+ */
+struct bug_frame *xsplice_find_bug(const char *eip, int *id)
+{
+    struct payload *data;
+    struct bug_frame *bug;
+    int i;
+
+    /* No locking since this list is only ever changed during apply or revert
+     * context. */
+    list_for_each_entry ( data, &applied_list, applied_list )
+    {
+        for (i = 0; i < 4; i++) {
+            if (!data->start_bug_frames[i])
+                continue;
+            if ( !((void *)eip >= data->payload_address &&
+                   (void *)eip < (data->payload_address + data->core_text_size)))
+                continue;
+
+            for ( bug = data->start_bug_frames[i]; bug != data->stop_bug_frames[i]; ++bug ) {
+                if ( bug_loc(bug) == eip )
+                {
+                    *id = i;
+                    return bug;
+                }
+            }
+        }
+    }
+
+    return NULL;
+}
+
+bool_t is_module(const void *ptr)
+{
+    struct payload *data;
+
+    /* No locking since this list is only ever changed during apply or revert
+     * context. */
+    list_for_each_entry ( data, &applied_list, applied_list )
+    {
+        if ( ptr >= data->payload_address &&
+             ptr < (data->payload_address + data->core_size))
+            return 1;
+    }
+
+    return 0;
+}
+
+bool_t is_active_module_text(unsigned long addr)
+{
+    struct payload *data;
+
+    /* No locking since this list is only ever changed during apply or revert
+     * context. */
+    list_for_each_entry ( data, &applied_list, applied_list )
+    {
+        if ( (void *)addr >= data->payload_address &&
+             (void *)addr < (data->payload_address + data->core_text_size))
+            return 1;
+    }
+
+    return 0;
+}
+
 static int __init xsplice_init(void)
 {
     register_keyhandler('x', xsplice_printall, "print xsplicing info", 1);
diff --git a/xen/include/asm-arm/bug.h b/xen/include/asm-arm/bug.h
index ab9e811..4df6b2a 100644
--- a/xen/include/asm-arm/bug.h
+++ b/xen/include/asm-arm/bug.h
@@ -31,6 +31,7 @@ struct bug_frame {
 #define BUGFRAME_warn   0
 #define BUGFRAME_bug    1
 #define BUGFRAME_assert 2
+#define BUGFRAME_NR     3
 
 /* Many versions of GCC doesn't support the asm %c parameter which would
  * be preferable to this unpleasantness. We use mergeable string
@@ -39,6 +40,7 @@ struct bug_frame {
  */
 #define BUG_FRAME(type, line, file, has_msg, msg) do {                      \
     BUILD_BUG_ON((line) >> 16);                                             \
+    BUILD_BUG_ON(type >= BUGFRAME_NR);                                      \
     asm ("1:"BUG_INSTR"\n"                                                  \
          ".pushsection .rodata.str, \"aMS\", %progbits, 1\n"                \
          "2:\t.asciz " __stringify(file) "\n"                               \
diff --git a/xen/include/asm-x86/bug.h b/xen/include/asm-x86/bug.h
index e868e85..5443191 100644
--- a/xen/include/asm-x86/bug.h
+++ b/xen/include/asm-x86/bug.h
@@ -9,6 +9,7 @@
 #define BUGFRAME_warn   1
 #define BUGFRAME_bug    2
 #define BUGFRAME_assert 3
+#define BUGFRAME_NR     4
 
 #ifndef __ASSEMBLY__
 
@@ -51,6 +52,7 @@ struct bug_frame {
 
 #define BUG_FRAME(type, line, ptr, second_frame, msg) do {                   \
     BUILD_BUG_ON((line) >> (BUG_LINE_LO_WIDTH + BUG_LINE_HI_WIDTH));         \
+    BUILD_BUG_ON((type) >= (BUGFRAME_NR));                                   \
     asm volatile ( _ASM_BUGFRAME_TEXT(second_frame)                          \
                    :: _ASM_BUGFRAME_INFO(type, line, ptr, msg) );            \
 } while (0)
diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h
index 548b64d..df57754 100644
--- a/xen/include/xen/kernel.h
+++ b/xen/include/xen/kernel.h
@@ -99,6 +99,7 @@ extern enum system_state {
 } system_state;
 
 bool_t is_active_kernel_text(unsigned long addr);
+bool_t is_active_text(unsigned long addr);
 
 #endif /* _LINUX_KERNEL_H */
 
diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h
index 61a9ec6..41b738a 100644
--- a/xen/include/xen/xsplice.h
+++ b/xen/include/xen/xsplice.h
@@ -26,8 +26,23 @@ int xsplice_control(struct xen_sysctl_xsplice_op *);
 
 #ifdef CONFIG_XSPLICE
 void do_xsplice(void);
+struct bug_frame *xsplice_find_bug(const char *eip, int *id);
+bool_t is_module(const void *addr);
+bool_t is_active_module_text(unsigned long addr);
 #else
 static inline void do_xsplice(void) { };
+static inline struct bug_frame *xsplice_find_bug(const char *eip, int *id)
+{
+	return NULL;
+}
+static inline bool_t is_module(const void *addr)
+{
+	return 0;
+}
+static inline bool_t is_active_module_text(unsigned long addr)
+{
+	return 0;
+}
 #endif
 
 /* Arch hooks */
-- 
2.1.0

  parent reply	other threads:[~2016-01-14 21:47 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-14 21:46 [PATCH v2] xSplice v1 implementation Konrad Rzeszutek Wilk
2016-01-14 21:46 ` [PATCH v2 01/13] xsplice: Design document (v5) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:31   ` Ross Lagerwall
2016-02-05 18:27     ` Konrad Rzeszutek Wilk
2016-02-05 18:34     ` Konrad Rzeszutek Wilk
2016-02-05 15:25   ` Jan Beulich
2016-02-05 21:47     ` Konrad Rzeszutek Wilk
2016-02-09  8:25       ` Jan Beulich
2016-01-14 21:47 ` [PATCH v2 02/13] hypervisor/arm/keyhandler: Declare struct cpu_user_regs; Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 03/13] xen/xsplice: Hypervisor implementation of XEN_XSPLICE_op (v7) Konrad Rzeszutek Wilk
2016-01-19 14:30   ` Ross Lagerwall
2016-02-06 22:35   ` Doug Goldstein
2016-02-09  8:28     ` Jan Beulich
2016-02-09 14:39     ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 04/13] libxc: Implementation of XEN_XSPLICE_op in libxc (v4) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-14 21:47 ` [PATCH v2 05/13] xen-xsplice: Tool to manipulate xsplice payloads (v3) Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:30   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 06/13] elf: Add relocation types to elfstructs.h Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 07/13] xsplice: Add helper elf routines (v2) Konrad Rzeszutek Wilk
2016-01-19 14:33   ` Ross Lagerwall
2016-02-05 18:38     ` Konrad Rzeszutek Wilk
2016-02-05 20:34       ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 08/13] xsplice: Implement payload loading (v2) Konrad Rzeszutek Wilk
2016-01-19 14:34   ` Ross Lagerwall
2016-01-19 16:59     ` Konrad Rzeszutek Wilk
2016-01-25 11:21       ` Ross Lagerwall
2016-01-19 16:45   ` Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 09/13] xsplice: Implement support for applying/reverting/replacing patches. (v2) Konrad Rzeszutek Wilk
2016-01-19 14:39   ` Ross Lagerwall
2016-01-19 16:55     ` Konrad Rzeszutek Wilk
2016-01-25 11:43       ` Ross Lagerwall
2016-02-05 19:30         ` Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 10/13] xen_hello_world.xsplice: Test payload for patching 'xen_extra_version' Konrad Rzeszutek Wilk
2016-01-19 11:14   ` Wei Liu
2016-01-19 14:57   ` Ross Lagerwall
2016-01-19 16:47   ` Ross Lagerwall
2016-01-14 21:47 ` Konrad Rzeszutek Wilk [this message]
2016-01-19 14:42   ` [PATCH v2 11/13] xsplice: Add support for bug frames. (v2) Ross Lagerwall
2016-01-14 21:47 ` [PATCH v2 12/13] xsplice: Add support for exception tables. (v2) Konrad Rzeszutek Wilk
2016-01-14 21:47 ` [PATCH v2 13/13] xsplice: Add support for alternatives Konrad Rzeszutek Wilk
2016-01-15 16:58 ` [PATCH v2] xSplice v1 implementation Konrad Rzeszutek Wilk
2016-01-25 11:57   ` Ross Lagerwall

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=1452808031-706-12-git-send-email-konrad.wilk@oracle.com \
    --to=konrad.wilk@oracle.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=mpohlack@amazon.com \
    --cc=ross.lagerwall@citrix.com \
    --cc=sasha.levin@oracle.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.