[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 01/16] common/symbols: Export hypervisor symbols to PV guest
Export Xen's symbols as {<address><type><name>} triplet via new XENPF_get_symbol hypercall Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> --- xen/arch/x86/platform_hypercall.c | 18 ++++++++++++ xen/arch/x86/x86_64/platform_hypercall.c | 2 ++ xen/common/symbols.c | 50 +++++++++++++++++++++++++++++++- xen/common/vsprintf.c | 2 +- xen/include/public/platform.h | 19 ++++++++++++ xen/include/xen/symbols.h | 7 +++-- 6 files changed, 94 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 2162811..cdb6886 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -23,6 +23,7 @@ #include <xen/cpu.h> #include <xen/pmstat.h> #include <xen/irq.h> +#include <xen/symbols.h> #include <asm/current.h> #include <public/platform.h> #include <acpi/cpufreq/processor_perf.h> @@ -601,6 +602,23 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) } break; + case XENPF_get_symbol: + { + char name[XEN_KSYM_NAME_LEN + 1]; + XEN_GUEST_HANDLE_64(char) nameh; + + guest_from_compat_handle(nameh, op->u.symdata.u.name); + + ret = xensyms_read(&op->u.symdata.symnum, &op->u.symdata.type, + &op->u.symdata.address, name); + + if ( !ret && copy_to_guest(nameh, name, XEN_KSYM_NAME_LEN + 1) ) + ret = -EFAULT; + if ( !ret && __copy_field_to_guest(u_xenpf_op, op, u.symdata) ) + ret = -EFAULT; + } + break; + default: ret = -ENOSYS; break; diff --git a/xen/arch/x86/x86_64/platform_hypercall.c b/xen/arch/x86/x86_64/platform_hypercall.c index b6f380e..795837f 100644 --- a/xen/arch/x86/x86_64/platform_hypercall.c +++ b/xen/arch/x86/x86_64/platform_hypercall.c @@ -32,6 +32,8 @@ CHECK_pf_pcpu_version; CHECK_pf_enter_acpi_sleep; #undef xen_pf_enter_acpi_sleep +#define xenpf_symdata compat_pf_symdata + #define COMPAT #define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) #define _XEN_GUEST_HANDLE_PARAM(t) XEN_GUEST_HANDLE_PARAM(t) diff --git a/xen/common/symbols.c b/xen/common/symbols.c index 45941e1..98f9534 100644 --- a/xen/common/symbols.c +++ b/xen/common/symbols.c @@ -17,6 +17,8 @@ #include <xen/lib.h> #include <xen/string.h> #include <xen/spinlock.h> +#include <public/platform.h> +#include <xen/guest_access.h> #ifdef SYMBOLS_ORIGIN extern const unsigned int symbols_offsets[1]; @@ -107,7 +109,7 @@ const char *symbols_lookup(unsigned long addr, unsigned long i, low, high, mid; unsigned long symbol_end = 0; - namebuf[KSYM_NAME_LEN] = 0; + namebuf[XEN_KSYM_NAME_LEN] = 0; namebuf[0] = 0; if (!is_active_kernel_text(addr)) @@ -148,3 +150,49 @@ const char *symbols_lookup(unsigned long addr, *offset = addr - symbols_address(low); return namebuf; } + +/* + * Get symbol type information. This is encoded as a single char at the + * beginning of the symbol name. + */ +static char symbols_get_symbol_type(unsigned int off) +{ + /* + * Get just the first code, look it up in the token table, + * and return the first char from this token. + */ + return symbols_token_table[symbols_token_index[symbols_names[off + 1]]]; +} + +/* + * Symbols are most likely accessed sequentially so we remember position from + * previous read. This can help us avoid the extra call to get_symbol_offset(). + */ +static uint64_t next_symbol, next_offset; +static DEFINE_SPINLOCK(symbols_mutex); + +int xensyms_read(uint32_t *symnum, uint32_t *type, uint64_t *address, char *name) +{ + if ( *symnum > symbols_num_syms ) + return -ERANGE; + if ( *symnum == symbols_num_syms ) + return 0; + + spin_lock(&symbols_mutex); + + if ( *symnum == 0 ) + next_offset = next_symbol = 0; + if ( next_symbol != *symnum ) + /* Non-sequential access */ + next_offset = get_symbol_offset(*symnum); + + *type = symbols_get_symbol_type(next_offset); + next_offset = symbols_expand_symbol(next_offset, name); + *address = symbols_offsets[*symnum] + SYMBOLS_ORIGIN; + + next_symbol = ++(*symnum); + + spin_unlock(&symbols_mutex); + + return 0; +} diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c index 1a6198e..c5ae187 100644 --- a/xen/common/vsprintf.c +++ b/xen/common/vsprintf.c @@ -275,7 +275,7 @@ static char *pointer(char *str, char *end, const char **fmt_ptr, case 'S': /* Symbol name unconditionally with offset and size */ { unsigned long sym_size, sym_offset; - char namebuf[KSYM_NAME_LEN+1]; + char namebuf[XEN_KSYM_NAME_LEN+1]; /* Advance parents fmt string, as we have consumed 's' or 'S' */ ++*fmt_ptr; diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h index 4341f54..ba9da49 100644 --- a/xen/include/public/platform.h +++ b/xen/include/public/platform.h @@ -527,6 +527,24 @@ struct xenpf_core_parking { typedef struct xenpf_core_parking xenpf_core_parking_t; DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t); +#define XENPF_get_symbol 61 +#define XEN_KSYM_NAME_LEN 127 +struct xenpf_symdata { + /* IN variables */ + uint32_t symnum; + + /* OUT variables */ + uint32_t type; + uint64_t address; + + union { + XEN_GUEST_HANDLE(char) name; + uint64_t pad; + } u; +}; +typedef struct xenpf_symdata xenpf_symdata_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_symdata_t); + /* * ` enum neg_errnoval * ` HYPERVISOR_platform_op(const struct xen_platform_op*); @@ -553,6 +571,7 @@ struct xen_platform_op { struct xenpf_cpu_hotadd cpu_add; struct xenpf_mem_hotadd mem_add; struct xenpf_core_parking core_parking; + struct xenpf_symdata symdata; uint8_t pad[128]; } u; }; diff --git a/xen/include/xen/symbols.h b/xen/include/xen/symbols.h index 87cd77d..adbf91d 100644 --- a/xen/include/xen/symbols.h +++ b/xen/include/xen/symbols.h @@ -2,8 +2,8 @@ #define _XEN_SYMBOLS_H #include <xen/types.h> - -#define KSYM_NAME_LEN 127 +#include <public/xen.h> +#include <public/platform.h> /* Lookup an address. */ const char *symbols_lookup(unsigned long addr, @@ -11,4 +11,7 @@ const char *symbols_lookup(unsigned long addr, unsigned long *offset, char *namebuf); +extern int xensyms_read(uint32_t *symnum, uint32_t *type, + uint64_t *address, char *name); + #endif /*_XEN_SYMBOLS_H*/ -- 1.8.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |