From: Ross Lagerwall <ross.lagerw...@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.lagerw...@citrix.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.w...@oracle.com> Reviewed-by: Andrew Cooper <andrew.coop...@citrix.com> --- Cc: Keir Fraser <k...@xen.org> Cc: Jan Beulich <jbeul...@suse.com> Cc: Andrew Cooper <andrew.coop...@citrix.com> 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. - Moved code around. - Changed per Andrew's recommendation. - Fixed style changes. - Made it compile under ARM (PRIu32,PRIu64) v4: Use 'struct virtual_region' - Rip more of the is_active_text code. - Use one function for the ->skip - Include test-case v5: Rip out the ->skip function. v7: Add a text check as well. Add Andrew's Reviewed-by. v8: Changed dprintk XENLOG_DEBUG to XENLOG_ERR --- --- xen/arch/x86/traps.c | 5 +++-- xen/common/xsplice.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ xen/include/xen/xsplice.h | 5 +++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index f73f7f3..8384158 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -50,6 +50,7 @@ #include <xen/paging.h> #include <xen/virtual_region.h> #include <xen/watchdog.h> +#include <xen/xsplice.h> #include <asm/system.h> #include <asm/io.h> #include <asm/atomic.h> @@ -1287,7 +1288,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 ) @@ -1314,7 +1315,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 12e5a13..97a0555 100644 --- a/xen/common/xsplice.c +++ b/xen/common/xsplice.c @@ -122,6 +122,32 @@ static int verify_payload(const xen_sysctl_xsplice_upload_t *upload, char *n) return 0; } +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->rw_addr && + ptr < (data->rw_addr + data->rw_size) ) + return 1; + + if ( ptr >= data->ro_addr && + ptr < (data->ro_addr + data->ro_size) ) + return 1; + + if ( ptr >= data->text_addr && + ptr < (data->text_addr + data->text_size) ) + return 1; + } + + return 0; +} + unsigned long xsplice_symbols_lookup_by_name(const char *symname) { struct payload *data; @@ -482,6 +508,30 @@ static int prepare_payload(struct payload *payload, region->start = (unsigned long)payload->text_addr; region->end = (unsigned long)(payload->text_addr + payload->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(*region->frame[i].bugs)) ) + { + dprintk(XENLOG_ERR, XSPLICE "%s: Wrong size of .bug_frames.%u!\n", + elf->name, i); + return -EINVAL; + } + + region->frame[i].bugs = sec->load_addr; + if ( sec->sec->sh_size) + region->frame[i].n_bugs = sec->sec->sh_size / + sizeof(*region->frame[i].bugs); + } + return 0; } diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h index 0599476..10e8a30 100644 --- a/xen/include/xen/xsplice.h +++ b/xen/include/xen/xsplice.h @@ -55,6 +55,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); unsigned long xsplice_symbols_lookup_by_name(const char *symname); /* Arch hooks. */ @@ -107,6 +108,10 @@ static inline int xsplice_op(struct xen_sysctl_xsplice_op *op) } 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@lists.xen.org http://lists.xen.org/xen-devel