[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/pv: Export pv_hypercall_table[] rather than working around it in several ways
The functions in compat.c are thing wrappers around the main hypercalls, massaging certain parameters. However, they second-guess the content of pv_hypercall_table[], which is problematic for the shim case. Instead, arrange for them to call via function pointer, which removes the need for pv_get_hypercall_handler(). With pv_hypercall_table[] exported, there is no need for pv_hypercall_table_replace(), so its single callsite gets modified to cope. The backing code behind __va(__pa()) is substantial, and there is no need to calculate it repeatedly (Xen's .rodata is also contiguous in the directmap). While adjusting the declarations, guard content in arch/x86/pv with CONFIG_PV. The net difference is: add/remove: 0/2 grow/shrink: 4/1 up/down: 176/-321 (-145) function old new delta pv_shim_setup_dom 1130 1266 +136 do_sched_op_compat 176 192 +16 compat_physdev_op_compat 90 106 +16 do_physdev_op_compat 98 106 +8 do_event_channel_op_compat 145 123 -22 pv_get_hypercall_handler 28 - -28 pv_hypercall_table_replace 271 - -271 Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx> --- xen/arch/x86/compat.c | 14 ++++++++++---- xen/arch/x86/pv/hypercall.c | 19 +------------------ xen/arch/x86/pv/shim.c | 21 +++++++++++++++------ xen/include/asm-x86/hypercall.h | 6 +++--- 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/xen/arch/x86/compat.c b/xen/arch/x86/compat.c index 9d376a4..a40ec29 100644 --- a/xen/arch/x86/compat.c +++ b/xen/arch/x86/compat.c @@ -17,12 +17,14 @@ typedef long ret_t; /* Legacy hypercall (as of 0x00030202). */ ret_t do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop) { + typeof(do_physdev_op) *fn = + (void *)pv_hypercall_table[__HYPERVISOR_physdev_op].native; struct physdev_op op; if ( unlikely(copy_from_guest(&op, uop, 1) != 0) ) return -EFAULT; - return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void)); + return fn(op.cmd, guest_handle_from_ptr(&uop.p->u, void)); } #ifndef COMPAT @@ -30,11 +32,14 @@ ret_t do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop) /* Legacy hypercall (as of 0x00030101). */ long do_sched_op_compat(int cmd, unsigned long arg) { + typeof(do_sched_op) *fn = + (void *)pv_hypercall_table[__HYPERVISOR_sched_op].native; + switch ( cmd ) { case SCHEDOP_yield: case SCHEDOP_block: - return do_sched_op(cmd, guest_handle_from_ptr(NULL, void)); + return fn(cmd, guest_handle_from_ptr(NULL, void)); case SCHEDOP_shutdown: TRACE_3D(TRC_SCHED_SHUTDOWN, @@ -52,6 +57,8 @@ long do_sched_op_compat(int cmd, unsigned long arg) /* Legacy hypercall (as of 0x00030202). */ long do_event_channel_op_compat(XEN_GUEST_HANDLE_PARAM(evtchn_op_t) uop) { + typeof(do_event_channel_op) *fn = + (void *)pv_hypercall_table[__HYPERVISOR_event_channel_op].native; struct evtchn_op op; if ( unlikely(copy_from_guest(&op, uop, 1) != 0) ) @@ -69,8 +76,7 @@ long do_event_channel_op_compat(XEN_GUEST_HANDLE_PARAM(evtchn_op_t) uop) case EVTCHNOP_bind_ipi: case EVTCHNOP_bind_vcpu: case EVTCHNOP_unmask: - return pv_get_hypercall_handler(__HYPERVISOR_event_channel_op, false) - (op.cmd, (unsigned long)&uop.p->u, 0, 0, 0, 0); + return fn(op.cmd, guest_handle_from_ptr(&uop.p->u, void)); default: return -ENOSYS; diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c index 3b72d6a..bbc3011 100644 --- a/xen/arch/x86/pv/hypercall.c +++ b/xen/arch/x86/pv/hypercall.c @@ -32,7 +32,7 @@ #define do_arch_1 paging_domctl_continuation -static const hypercall_table_t pv_hypercall_table[] = { +const hypercall_table_t pv_hypercall_table[] = { COMPAT_CALL(set_trap_table), HYPERCALL(mmu_update), COMPAT_CALL(set_gdt), @@ -320,23 +320,6 @@ void hypercall_page_initialise_ring1_kernel(void *hypercall_page) *(u16 *)(p+ 6) = (HYPERCALL_VECTOR << 8) | 0xcd; /* int $xx */ } -void __init pv_hypercall_table_replace(unsigned int hypercall, - hypercall_fn_t * native, - hypercall_fn_t *compat) -{ -#define HANDLER_POINTER(f) \ - ((unsigned long *)__va(__pa(&pv_hypercall_table[hypercall].f))) - write_atomic(HANDLER_POINTER(native), (unsigned long)native); - write_atomic(HANDLER_POINTER(compat), (unsigned long)compat); -#undef HANDLER_POINTER -} - -hypercall_fn_t *pv_get_hypercall_handler(unsigned int hypercall, bool compat) -{ - return compat ? pv_hypercall_table[hypercall].compat - : pv_hypercall_table[hypercall].native; -} - /* * Local variables: * mode: C diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c index d5383dc..9651952 100644 --- a/xen/arch/x86/pv/shim.c +++ b/xen/arch/x86/pv/shim.c @@ -160,6 +160,7 @@ void __init pv_shim_setup_dom(struct domain *d, l4_pgentry_t *l4start, unsigned long console_va, unsigned long vphysmap, start_info_t *si) { + hypercall_table_t *rw_pv_hypercall_table; uint64_t param = 0; long rc; @@ -205,12 +206,20 @@ void __init pv_shim_setup_dom(struct domain *d, l4_pgentry_t *l4start, mfn_x(console_mfn), vphysmap); consoled_set_ring_addr(page); } - pv_hypercall_table_replace(__HYPERVISOR_event_channel_op, - (hypercall_fn_t *)pv_shim_event_channel_op, - (hypercall_fn_t *)pv_shim_event_channel_op); - pv_hypercall_table_replace(__HYPERVISOR_grant_table_op, - (hypercall_fn_t *)pv_shim_grant_table_op, - (hypercall_fn_t *)pv_shim_grant_table_op); + + /* + * Find a writeable mapping to pv_hypercall_table[] in the directmap + * insert some shim-specific hypercall handlers. + */ + rw_pv_hypercall_table = __va(__pa(pv_hypercall_table)); + rw_pv_hypercall_table[__HYPERVISOR_event_channel_op].native = + rw_pv_hypercall_table[__HYPERVISOR_event_channel_op].compat = + (hypercall_fn_t *)pv_shim_event_channel_op; + + rw_pv_hypercall_table[__HYPERVISOR_grant_table_op].native = + rw_pv_hypercall_table[__HYPERVISOR_grant_table_op].compat = + (hypercall_fn_t *)pv_shim_grant_table_op; + guest = d; /* diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h index b9f3ecf..1cc2e37 100644 --- a/xen/include/asm-x86/hypercall.h +++ b/xen/include/asm-x86/hypercall.h @@ -25,12 +25,12 @@ typedef struct { extern const hypercall_args_t hypercall_args_table[NR_hypercalls]; +#ifdef CONFIG_PV +extern const hypercall_table_t pv_hypercall_table[]; void pv_hypercall(struct cpu_user_regs *regs); void hypercall_page_initialise_ring3_kernel(void *hypercall_page); void hypercall_page_initialise_ring1_kernel(void *hypercall_page); -void pv_hypercall_table_replace(unsigned int hypercall, hypercall_fn_t * native, - hypercall_fn_t *compat); -hypercall_fn_t *pv_get_hypercall_handler(unsigned int hypercall, bool compat); +#endif /* * Both do_mmuext_op() and do_mmu_update(): -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |