[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v1 10/11] xsplice: Add support for exception tables
On Tue, Nov 03, 2015 at 06:16:07PM +0000, Ross Lagerwall wrote: > Add support for exception tables contained within xsplice modules. If an > exception occurs search either the main exception table or a particular > active module's exception table depending on the instruction pointer. s/module/payload/ > > Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> > --- > xen/arch/x86/extable.c | 36 ++++++++++++++++++++++-------------- > xen/common/xsplice.c | 41 +++++++++++++++++++++++++++++++++++++++++ > xen/include/asm-x86/uaccess.h | 5 +++++ > xen/include/xen/xsplice.h | 2 ++ > 4 files changed, 70 insertions(+), 14 deletions(-) > > diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c > index 89b5bcb..2787a92 100644 > --- a/xen/arch/x86/extable.c > +++ b/xen/arch/x86/extable.c > @@ -4,6 +4,7 @@ > #include <xen/perfc.h> > #include <xen/sort.h> > #include <xen/spinlock.h> > +#include <xen/xsplice.h> > #include <asm/uaccess.h> > > #define EX_FIELD(ptr, field) ((unsigned long)&(ptr)->field + (ptr)->field) > @@ -18,7 +19,7 @@ static inline unsigned long ex_cont(const struct > exception_table_entry *x) > return EX_FIELD(x, cont); > } > > -static int __init cmp_ex(const void *a, const void *b) > +static int cmp_ex(const void *a, const void *b) > { > const struct exception_table_entry *l = a, *r = b; > unsigned long lip = ex_addr(l); > @@ -33,7 +34,7 @@ static int __init cmp_ex(const void *a, const void *b) > } > > #ifndef swap_ex > -static void __init swap_ex(void *a, void *b, int size) > +static void swap_ex(void *a, void *b, int size) > { > struct exception_table_entry *l = a, *r = b, tmp; > long delta = b - a; > @@ -46,19 +47,23 @@ static void __init swap_ex(void *a, void *b, int size) > } > #endif > > -void __init sort_exception_tables(void) > +void sort_exception_table(struct exception_table_entry *start, > + struct exception_table_entry *stop) > { > - sort(__start___ex_table, __stop___ex_table - __start___ex_table, > - sizeof(struct exception_table_entry), cmp_ex, swap_ex); > - sort(__start___pre_ex_table, > - __stop___pre_ex_table - __start___pre_ex_table, > + sort(start, stop - start, > sizeof(struct exception_table_entry), cmp_ex, swap_ex); > } > > -static inline unsigned long > -search_one_table(const struct exception_table_entry *first, > - const struct exception_table_entry *last, > - unsigned long value) > +void __init sort_exception_tables(void) > +{ > + sort_exception_table(__start___ex_table, __stop___ex_table); > + sort_exception_table(__start___pre_ex_table, __stop___pre_ex_table); > +} > + > +unsigned long > +search_one_extable(const struct exception_table_entry *first, > + const struct exception_table_entry *last, > + unsigned long value) > { > const struct exception_table_entry *mid; > long diff; > @@ -80,15 +85,18 @@ search_one_table(const struct exception_table_entry > *first, > unsigned long > search_exception_table(unsigned long addr) > { > - return search_one_table( > - __start___ex_table, __stop___ex_table-1, addr); > + if ( likely(is_kernel(addr)) ) > + return search_one_extable( > + __start___ex_table, __stop___ex_table-1, addr); > + else > + return search_module_extables(addr); > } > > unsigned long > search_pre_exception_table(struct cpu_user_regs *regs) > { > unsigned long addr = (unsigned long)regs->eip; > - unsigned long fixup = search_one_table( > + unsigned long fixup = search_one_extable( > __start___pre_ex_table, __stop___pre_ex_table-1, addr); > if ( fixup ) > { > diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c > index 982954b..c5a403b 100644 > --- a/xen/common/xsplice.c > +++ b/xen/common/xsplice.c > @@ -45,6 +45,10 @@ struct payload { > > struct bug_frame *start_bug_frames[4]; > struct bug_frame *stop_bug_frames[4]; > +#ifdef CONFIG_X86 > + struct exception_table_entry *start_ex_table; > + struct exception_table_entry *stop_ex_table; > +#endif > > char id[XEN_XSPLICE_NAME_SIZE + 1]; /* Name of it. */ > }; > @@ -691,6 +695,17 @@ static int find_special_sections(struct payload *payload, > payload->stop_bug_frames[i] = (struct bug_frame *)(sec->load_addr + > sec->sec->sh_size); > } > > +#ifdef CONFIG_X86 > + sec = xsplice_elf_sec_by_name(elf, ".ex_table"); > + if ( sec ) > + { > + payload->start_ex_table = (struct exception_table_entry > *)sec->load_addr; > + payload->stop_ex_table = (struct exception_table_entry > *)(sec->load_addr + sec->sec->sh_size); Please double-check that sh_size is not some funny value. For example it may be 0, or worst - not aligned to the size of 'struct exception_table_entry'! > + > + sort_exception_table(payload->start_ex_table, > payload->stop_ex_table); > + } > +#endif > + > return 0; > } > > @@ -999,6 +1014,32 @@ bool_t is_active_module_text(unsigned long addr) > return false; > } > > +#ifdef CONFIG_X86 > +unsigned long search_module_extables(unsigned long addr) > +{ > + struct payload *data; > + unsigned long ret; > + > + /* No locking since this list is only ever changed during apply or revert > + * context. */ > + list_for_each_entry ( data, &applied_list, applied_list ) > + { > + if ( !data->start_ex_table ) > + continue; > + if ( !((void *)addr >= data->module_address && > + (void *)addr < (data->module_address + data->core_text_size))) The last ')' needs to have space before it. > + continue; > + > + ret = search_one_extable(data->start_ex_table, data->stop_ex_table - > 1, > + addr); > + if ( ret ) > + return ret; > + } > + > + return 0; > +} > +#endif > + > static int __init xsplice_init(void) > { > register_keyhandler('x', xsplice_printall, "print xsplicing info", 1); > diff --git a/xen/include/asm-x86/uaccess.h b/xen/include/asm-x86/uaccess.h > index 947470d..9e67bf0 100644 > --- a/xen/include/asm-x86/uaccess.h > +++ b/xen/include/asm-x86/uaccess.h > @@ -276,6 +276,11 @@ extern struct exception_table_entry > __start___pre_ex_table[]; > extern struct exception_table_entry __stop___pre_ex_table[]; > > extern unsigned long search_exception_table(unsigned long); > +extern unsigned long search_one_extable(const struct exception_table_entry > *first, > + const struct exception_table_entry > *last, > + unsigned long value); > extern void sort_exception_tables(void); > +extern void sort_exception_table(struct exception_table_entry *start, > + struct exception_table_entry *stop); > > #endif /* __X86_UACCESS_H__ */ > diff --git a/xen/include/xen/xsplice.h b/xen/include/xen/xsplice.h > index 772fa3a..485eb08 100644 > --- a/xen/include/xen/xsplice.h > +++ b/xen/include/xen/xsplice.h > @@ -26,6 +26,8 @@ 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); > > +unsigned long search_module_extables(unsigned long addr); > + > /* Arch hooks */ > int xsplice_verify_elf(uint8_t *data, ssize_t len); > int xsplice_perform_rel(struct xsplice_elf *elf, > -- > 2.4.3 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |