[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86, xsplice: Print payload's symbol name and payload name in backtraces
commit d5ccf4482e4f3c99f1bcae242ce67bdd51f52537 Author: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> AuthorDate: Wed Apr 27 11:30:25 2016 -0400 Commit: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> CommitDate: Fri Apr 29 03:58:47 2016 -0400 x86, xsplice: Print payload's symbol name and payload name in backtraces Naturally the backtrace is presented when an instruction hits an bug_frame or %p is used. The payloads do not support bug_frames yet - however the functions the payloads call could hit an BUG() or WARN(). The traps.c has logic to scan for it this - and eventually it will find the correct bug_frame and the walk the stack using %p to print the backtrace. For %p and symbols to print a string - the 'is_active_kernel_text' is consulted which uses an 'struct virtual_region'. Therefore we register our start->end addresses so that 'is_active_kernel_text' will include our payload address. We also register our symbol lookup table function so that it can scan the list of payloads and retrieve the correct name. Lastly we change vsprintf to take into account s and namebuf. For core code they are the same, but for payloads they are different. This gets us: Xen call trace: [<ffff82d080a00041>] revert_hook+0x31/0x35 [xen_hello_world] [<ffff82d0801431bd>] xsplice.c#revert_payload+0x86/0xc6 [<ffff82d080143502>] check_for_xsplice_work+0x233/0x3cd [<ffff82d08017a0b2>] domain.c#continue_idle_domain+0x9/0x1f Which is great if payloads have similar or same symbol names. Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> Release-acked-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- xen/common/vsprintf.c | 12 +++++++++ xen/common/xsplice.c | 69 ++++++++++++++++++++++++++++++++++++++++++++--- xen/include/xen/xsplice.h | 1 + 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c index 18d2634..70e1edf 100644 --- a/xen/common/vsprintf.c +++ b/xen/common/vsprintf.c @@ -20,6 +20,7 @@ #include <xen/symbols.h> #include <xen/lib.h> #include <xen/sched.h> +#include <xen/xsplice.h> #include <asm/div64.h> #include <asm/page.h> @@ -354,6 +355,17 @@ static char *pointer(char *str, char *end, const char **fmt_ptr, str = number(str, end, sym_size, 16, -1, -1, SPECIAL); } + /* + * namebuf contents and s for core hypervisor are same but for xSplice + * payloads they differ (namebuf contains the name of the payload). + */ + if ( namebuf != s ) + { + str = string(str, end, " [", -1, -1, 0); + str = string(str, end, namebuf, -1, -1, 0); + str = string(str, end, "]", -1, -1, 0); + } + return str; } diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c index 3d56c04..e7872c6 100644 --- a/xen/common/xsplice.c +++ b/xen/common/xsplice.c @@ -14,7 +14,9 @@ #include <xen/smp.h> #include <xen/softirq.h> #include <xen/spinlock.h> +#include <xen/string.h> #include <xen/symbols.h> +#include <xen/virtual_region.h> #include <xen/vmap.h> #include <xen/wait.h> #include <xen/xsplice_elf.h> @@ -31,10 +33,9 @@ static LIST_HEAD(payload_list); /* * Patches which have been applied. Need RCU in case we crash (and then - * traps code would iterate via applied_list) when adding entries on the list. - * - * Note: There are no 'rcu_applied_lock' as we don't iterate yet the list. + * traps code would iterate via applied_list) when adding entries onthe list. */ +static DEFINE_RCU_READ_LOCK(rcu_applied_lock); static LIST_HEAD(applied_list); static unsigned int payload_cnt; @@ -56,6 +57,8 @@ struct payload { unsigned int nfuncs; /* Nr of functions to patch. */ const struct xsplice_symbol *symtab; /* All symbols. */ const char *strtab; /* Pointer to .strtab. */ + struct virtual_region region; /* symbol, bug.frame patching and + exception table (x86). */ unsigned int nsyms; /* Nr of entries in .strtab and symbols. */ char name[XEN_XSPLICE_NAME_SIZE]; /* Name of it. */ }; @@ -139,6 +142,55 @@ unsigned long xsplice_symbols_lookup_by_name(const char *symname) return 0; } +static const char *xsplice_symbols_lookup(unsigned long addr, + unsigned long *symbolsize, + unsigned long *offset, + char *namebuf) +{ + const struct payload *data; + unsigned int i, best; + const void *va = (const void *)addr; + const char *n = NULL; + + /* + * 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 ( va < data->text_addr || + va >= (data->text_addr + data->text_size) ) + continue; + + best = UINT_MAX; + + for ( i = 0; i < data->nsyms; i++ ) + { + if ( data->symtab[i].value <= addr && + (best == UINT_MAX || + data->symtab[best].value < data->symtab[i].value) ) + best = i; + } + + if ( best == UINT_MAX ) + break; + + if ( symbolsize ) + *symbolsize = data->symtab[best].size; + if ( offset ) + *offset = addr - data->symtab[best].value; + if ( namebuf ) + strlcpy(namebuf, data->name, KSYM_NAME_LEN); + + n = data->symtab[best].name; + break; + } + rcu_read_unlock(&rcu_applied_lock); + + return n; +} + static struct payload *find_payload(const char *name) { struct payload *data, *found = NULL; @@ -364,6 +416,7 @@ static int prepare_payload(struct payload *payload, const struct xsplice_elf_sec *sec; unsigned int i; struct xsplice_patch_func *f; + struct virtual_region *region; sec = xsplice_elf_sec_by_name(elf, ELF_XSPLICE_FUNC); ASSERT(sec); @@ -420,6 +473,13 @@ static int prepare_payload(struct payload *payload, } } + /* Setup the virtual region with proper data. */ + region = &payload->region; + + region->symbols_lookup = xsplice_symbols_lookup; + region->start = payload->text_addr; + region->end = payload->text_addr + payload->text_size; + return 0; } @@ -496,6 +556,7 @@ static int build_symbol_table(struct payload *payload, if ( is_payload_symbol(elf, elf->sym + i) ) { symtab[nsyms].name = strtab + strtab_len; + symtab[nsyms].size = elf->sym[i].sym->st_size; symtab[nsyms].value = elf->sym[i].sym->st_value; symtab[nsyms].new_symbol = 0; /* May be overwritten below. */ strtab_len += strlcpy(strtab + strtab_len, elf->sym[i].name, @@ -779,6 +840,7 @@ static int apply_payload(struct payload *data) * The applied_list is iterated by the trap code. */ list_add_tail_rcu(&data->applied_list, &applied_list); + register_virtual_region(&data->region); return 0; } @@ -801,6 +863,7 @@ static int revert_payload(struct payload *data) * The applied_list is iterated by the trap code. */ list_del_rcu(&data->applied_list); + unregister_virtual_region(&data->region); return 0; } diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h index 0a6020d..331c383 100644 --- a/xen/include/xen/xsplice.h +++ b/xen/include/xen/xsplice.h @@ -22,6 +22,7 @@ struct xen_sysctl_xsplice_op; struct xsplice_symbol { const char *name; unsigned long value; + unsigned int size; bool_t new_symbol; }; -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |