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

[Xen-devel] [PATCH v4 22/34] xsplice: Add support for bug frames.



From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>

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.

We also include a test-case - which will test the function that was
patched to make sure it has the right value. And will only be triggered
if something has gone horribly wrong.

P.S.
If one really wants to test, insert an WARN_ON(1) at the end of
the revert_hook.

Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>

---
Cc: Keir Fraser <keir@xxxxxxx>
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>

v2:- s/module/payload/
   - add build time check in case amount of bug frames expands.
   - add define for the number of bug-frames.
v3:
  - add missing BUGFRAME_NR, squash s/core_size/core/ in earlier patch.
v4:- Add comment about it being optional.
  - Moved code around.
  - Changed per Andrew's recommendation.
  - Fixed style changes.
  - Made it compile under ARM (PRIu32,PRIu64)
v5: Use 'struct virtual_region'
  - Rip more of the is_active_text code.
  - Use one function for the ->skip
v6: Include test-case
---
 xen/arch/x86/test/xen_hello_world.c |  6 ++++++
 xen/arch/x86/traps.c                |  5 +++--
 xen/common/xsplice.c                | 42 +++++++++++++++++++++++++++++++++++++
 xen/include/xen/xsplice.h           |  5 +++++
 4 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/test/xen_hello_world.c 
b/xen/arch/x86/test/xen_hello_world.c
index d2b3cc2..5364114 100644
--- a/xen/arch/x86/test/xen_hello_world.c
+++ b/xen/arch/x86/test/xen_hello_world.c
@@ -19,11 +19,17 @@ extern const char *xen_extra_version(void);
 void apply_hook(void)
 {
     printk(KERN_DEBUG "Hook executing.\n");
+    /* The hook is called  _after_ the patching. */
+    if ( strcmp(xen_extra_version(), "Hello World") )
+        BUG();
 }
 
 void revert_hook(void)
 {
     printk(KERN_DEBUG "Hook unloaded.\n");
+    /* The hook is called  _after_ the unpatching. */
+    if ( !strcmp(xen_extra_version(), "Hello World") )
+        BUG();
 }
 
 XSPLICE_LOAD_HOOK(apply_hook);
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index eeada97..f35fd1a 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -49,6 +49,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>
@@ -1196,7 +1197,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_patch(filename) )
         goto die;
     fixup = strlen(filename);
     if ( fixup > 50 )
@@ -1223,7 +1224,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_patch(predicate) )
             predicate = "<unknown>";
 
         printk("Assertion '%s' failed at %s%s:%d\n",
diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c
index 5fb1867..49f0d6e 100644
--- a/xen/common/xsplice.c
+++ b/xen/common/xsplice.c
@@ -117,6 +117,25 @@ static bool_t ignore_region(unsigned int flag, unsigned 
long priv)
     return !(flag & priv);
 }
 
+
+bool_t is_patch(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;
+}
+
 uint64_t xsplice_symbols_lookup_by_name(const char *symname)
 {
     struct payload *data;
@@ -468,6 +487,29 @@ static int prepare_payload(struct payload *payload,
     region->start = (unsigned long)payload->payload_address;
     region->end = (unsigned long)(payload->payload_address + 
payload->core_text_size);
 
+
+    /* Optional sections. */
+    for ( i = 0; i < BUGFRAME_NR; i++ )
+    {
+        char str[14];
+
+        snprintf(str, sizeof str, ".bug_frames.%u", 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)) )
+        {
+            dprintk(XENLOG_DEBUG, "%s%s: Wrong size of .bug_frames.%u!\n",
+                    XSPLICE, elf->name, i);
+            return -EINVAL;
+        }
+        region->frame[i].bugs = (struct bug_frame *)sec->load_addr;
+        region->frame[i].n_bugs = sec->sec->sh_size / sizeof(struct bug_frame);
+        if ( !(region->priv & CHECKING_BUG_FRAME) )
+            region->priv |= CHECKING_BUG_FRAME;
+    }
     return 0;
 }
 
diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h
index 2e2fb78..16d35b8 100644
--- a/xen/include/xen/xsplice.h
+++ b/xen/include/xen/xsplice.h
@@ -42,6 +42,7 @@ struct xsplice_symbol {
 
 int xsplice_op(struct xen_sysctl_xsplice_op *);
 void check_for_xsplice_work(void);
+bool_t is_patch(const void *addr);
 uint64_t xsplice_symbols_lookup_by_name(const char *symname);
 
 /* Arch hooks. */
@@ -104,6 +105,10 @@ static inline int xsplice_op(struct xen_sysctl_xsplice_op 
*op)
     return -ENOSYS;
 }
 static inline void check_for_xsplice_work(void) { };
+static inline bool_t is_patch(const void *addr)
+{
+    return 0;
+}
 #endif /* CONFIG_XSPLICE */
 
 #endif /* __XEN_XSPLICE_H__ */
-- 
2.5.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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