[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v9 17/27] 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. Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@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. - 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 v9: Removed pointless check on the side of conditional (sec->sec->sh_size) - Added const. - Use RCU list. --- --- xen/arch/x86/traps.c | 5 +++-- xen/common/xsplice.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ xen/include/xen/xsplice.h | 5 +++++ 3 files changed, 59 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 72a3b88..11b19dd 100644 --- a/xen/common/xsplice.c +++ b/xen/common/xsplice.c @@ -123,6 +123,35 @@ static int verify_payload(const xen_sysctl_xsplice_upload_t *upload, char *n) return 0; } +bool_t is_patch(const void *ptr) +{ + const struct payload *data; + bool_t r = 0; + + /* + * Only RCU locking since this list is only ever changed during apply + * or revert context. And in case it dies there we need an safe list. + */ + rcu_read_lock(&rcu_applied_lock); + list_for_each_entry_rcu ( data, &applied_list, applied_list ) + { + if ( (ptr >= data->rw_addr && + ptr < (data->rw_addr + data->rw_size)) || + (ptr >= data->ro_addr && + ptr < (data->ro_addr + data->ro_size)) || + (ptr >= data->text_addr && + ptr < (data->text_addr + data->text_size)) ) + { + r = 1; + break; + } + + } + rcu_read_unlock(&rcu_applied_lock); + + return r; +} + void *xsplice_symbols_lookup_by_name(const char *symname) { const struct payload *data; @@ -482,6 +511,28 @@ static int prepare_payload(struct payload *payload, region->start = payload->text_addr; region->end = 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 % 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; + 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 bb8baee..7f4c8f7 100644 --- a/xen/include/xen/xsplice.h +++ b/xen/include/xen/xsplice.h @@ -29,6 +29,7 @@ struct xsplice_symbol { int xsplice_op(struct xen_sysctl_xsplice_op *); void check_for_xsplice_work(void); void *xsplice_symbols_lookup_by_name(const char *symname); +bool_t is_patch(const void *addr); /* Arch hooks. */ int arch_xsplice_verify_elf(const struct xsplice_elf *elf); @@ -76,6 +77,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@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |