[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/hypercall: Split out PV hypercall infrastructure
Repurpose arch/x86/hypercall.c to be common x86 hypercall infrastructure, and move the PV specific routines to arch/x86/pv/hypercall.c This is purely code motion. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> --- xen/arch/x86/Makefile | 1 + xen/arch/x86/hypercall.c | 226 +------------------------------------- xen/arch/x86/pv/Makefile | 1 + xen/arch/x86/{ => pv}/hypercall.c | 59 +--------- 4 files changed, 8 insertions(+), 279 deletions(-) create mode 100644 xen/arch/x86/pv/Makefile copy xen/arch/x86/{ => pv}/hypercall.c (84%) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 007dced..10f519e 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -4,6 +4,7 @@ subdir-y += genapic subdir-y += hvm subdir-y += mm subdir-$(CONFIG_XENOPROF) += oprofile +subdir-y += pv subdir-y += x86_64 alternative-y := alternative.init.o diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c index c0718f8..f807332 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/hypercall.c @@ -1,6 +1,8 @@ /****************************************************************************** * arch/x86/hypercall.c * + * Common x86 hypercall infrastructure. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -17,9 +19,7 @@ * Copyright (c) 2015,2016 Citrix Systems Ltd. */ -#include <xen/compiler.h> #include <xen/hypercall.h> -#include <xen/trace.h> #define ARGS(x, n) \ [ __HYPERVISOR_ ## x ] = { n, n } @@ -74,228 +74,6 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] = #undef COMP #undef ARGS -#define HYPERCALL(x) \ - [ __HYPERVISOR_ ## x ] = { (hypercall_fn_t *) do_ ## x, \ - (hypercall_fn_t *) do_ ## x } -#define COMPAT_CALL(x) \ - [ __HYPERVISOR_ ## x ] = { (hypercall_fn_t *) do_ ## x, \ - (hypercall_fn_t *) compat_ ## x } - -#define do_arch_1 paging_domctl_continuation - -static const hypercall_table_t pv_hypercall_table[] = { - COMPAT_CALL(set_trap_table), - HYPERCALL(mmu_update), - COMPAT_CALL(set_gdt), - HYPERCALL(stack_switch), - COMPAT_CALL(set_callbacks), - HYPERCALL(fpu_taskswitch), - HYPERCALL(sched_op_compat), - COMPAT_CALL(platform_op), - HYPERCALL(set_debugreg), - HYPERCALL(get_debugreg), - COMPAT_CALL(update_descriptor), - COMPAT_CALL(memory_op), - COMPAT_CALL(multicall), - COMPAT_CALL(update_va_mapping), - COMPAT_CALL(set_timer_op), - HYPERCALL(event_channel_op_compat), - COMPAT_CALL(xen_version), - HYPERCALL(console_io), - COMPAT_CALL(physdev_op_compat), - COMPAT_CALL(grant_table_op), - COMPAT_CALL(vm_assist), - COMPAT_CALL(update_va_mapping_otherdomain), - COMPAT_CALL(iret), - COMPAT_CALL(vcpu_op), - HYPERCALL(set_segment_base), - COMPAT_CALL(mmuext_op), - COMPAT_CALL(xsm_op), - COMPAT_CALL(nmi_op), - COMPAT_CALL(sched_op), - COMPAT_CALL(callback_op), -#ifdef CONFIG_XENOPROF - COMPAT_CALL(xenoprof_op), -#endif - HYPERCALL(event_channel_op), - COMPAT_CALL(physdev_op), - HYPERCALL(hvm_op), - HYPERCALL(sysctl), - HYPERCALL(domctl), -#ifdef CONFIG_KEXEC - COMPAT_CALL(kexec_op), -#endif -#ifdef CONFIG_TMEM - HYPERCALL(tmem_op), -#endif - HYPERCALL(xenpmu_op), - COMPAT_CALL(dm_op), - HYPERCALL(mca), - HYPERCALL(arch_1), -}; - -#undef do_arch_1 -#undef COMPAT_CALL -#undef HYPERCALL - -void pv_hypercall(struct cpu_user_regs *regs) -{ - struct vcpu *curr = current; - unsigned long eax; - - ASSERT(guest_kernel_mode(curr, regs)); - - eax = is_pv_32bit_vcpu(curr) ? regs->_eax : regs->rax; - - BUILD_BUG_ON(ARRAY_SIZE(pv_hypercall_table) > - ARRAY_SIZE(hypercall_args_table)); - - if ( (eax >= ARRAY_SIZE(pv_hypercall_table)) || - !pv_hypercall_table[eax].native ) - { - regs->rax = -ENOSYS; - return; - } - - curr->hcall_preempted = false; - - if ( !is_pv_32bit_vcpu(curr) ) - { - unsigned long rdi = regs->rdi; - unsigned long rsi = regs->rsi; - unsigned long rdx = regs->rdx; - unsigned long r10 = regs->r10; - unsigned long r8 = regs->r8; - unsigned long r9 = regs->r9; - -#ifndef NDEBUG - /* Deliberately corrupt parameter regs not used by this hypercall. */ - switch ( hypercall_args_table[eax].native ) - { - case 0: rdi = 0xdeadbeefdeadf00dUL; - case 1: rsi = 0xdeadbeefdeadf00dUL; - case 2: rdx = 0xdeadbeefdeadf00dUL; - case 3: r10 = 0xdeadbeefdeadf00dUL; - case 4: r8 = 0xdeadbeefdeadf00dUL; - case 5: r9 = 0xdeadbeefdeadf00dUL; - } -#endif - if ( unlikely(tb_init_done) ) - { - unsigned long args[6] = { rdi, rsi, rdx, r10, r8, r9 }; - - __trace_hypercall(TRC_PV_HYPERCALL_V2, eax, args); - } - - regs->rax = pv_hypercall_table[eax].native(rdi, rsi, rdx, r10, r8, r9); - -#ifndef NDEBUG - if ( !curr->hcall_preempted ) - { - /* Deliberately corrupt parameter regs used by this hypercall. */ - switch ( hypercall_args_table[eax].native ) - { - case 6: regs->r9 = 0xdeadbeefdeadf00dUL; - case 5: regs->r8 = 0xdeadbeefdeadf00dUL; - case 4: regs->r10 = 0xdeadbeefdeadf00dUL; - case 3: regs->rdx = 0xdeadbeefdeadf00dUL; - case 2: regs->rsi = 0xdeadbeefdeadf00dUL; - case 1: regs->rdi = 0xdeadbeefdeadf00dUL; - } - } -#endif - } - else - { - unsigned int ebx = regs->_ebx; - unsigned int ecx = regs->_ecx; - unsigned int edx = regs->_edx; - unsigned int esi = regs->_esi; - unsigned int edi = regs->_edi; - unsigned int ebp = regs->_ebp; - -#ifndef NDEBUG - /* Deliberately corrupt parameter regs not used by this hypercall. */ - switch ( hypercall_args_table[eax].compat ) - { - case 0: ebx = 0xdeadf00d; - case 1: ecx = 0xdeadf00d; - case 2: edx = 0xdeadf00d; - case 3: esi = 0xdeadf00d; - case 4: edi = 0xdeadf00d; - case 5: ebp = 0xdeadf00d; - } -#endif - - if ( unlikely(tb_init_done) ) - { - unsigned long args[6] = { ebx, ecx, edx, esi, edi, ebp }; - - __trace_hypercall(TRC_PV_HYPERCALL_V2, eax, args); - } - - curr->hcall_compat = true; - regs->_eax = pv_hypercall_table[eax].compat(ebx, ecx, edx, esi, edi, ebp); - curr->hcall_compat = false; - -#ifndef NDEBUG - if ( !curr->hcall_preempted ) - { - /* Deliberately corrupt parameter regs used by this hypercall. */ - switch ( hypercall_args_table[eax].compat ) - { - case 6: regs->_ebp = 0xdeadf00d; - case 5: regs->_edi = 0xdeadf00d; - case 4: regs->_esi = 0xdeadf00d; - case 3: regs->_edx = 0xdeadf00d; - case 2: regs->_ecx = 0xdeadf00d; - case 1: regs->_ebx = 0xdeadf00d; - } - } -#endif - } - - /* - * PV guests use SYSCALL or INT $0x82 to make a hypercall, both of which - * have trap semantics. If the hypercall has been preempted, rewind the - * instruction pointer to reexecute the instruction. - */ - if ( curr->hcall_preempted ) - regs->rip -= 2; - - perfc_incr(hypercalls); -} - -void arch_do_multicall_call(struct mc_state *state) -{ - if ( !is_pv_32bit_vcpu(current) ) - { - struct multicall_entry *call = &state->call; - - if ( (call->op < ARRAY_SIZE(pv_hypercall_table)) && - pv_hypercall_table[call->op].native ) - call->result = pv_hypercall_table[call->op].native( - call->args[0], call->args[1], call->args[2], - call->args[3], call->args[4], call->args[5]); - else - call->result = -ENOSYS; - } -#ifdef CONFIG_COMPAT - else - { - struct compat_multicall_entry *call = &state->compat_call; - - if ( (call->op < ARRAY_SIZE(pv_hypercall_table)) && - pv_hypercall_table[call->op].compat ) - call->result = pv_hypercall_table[call->op].compat( - call->args[0], call->args[1], call->args[2], - call->args[3], call->args[4], call->args[5]); - else - call->result = -ENOSYS; - } -#endif -} - /* * Local variables: * mode: C diff --git a/xen/arch/x86/pv/Makefile b/xen/arch/x86/pv/Makefile new file mode 100644 index 0000000..de21937 --- /dev/null +++ b/xen/arch/x86/pv/Makefile @@ -0,0 +1 @@ +obj-y += hypercall.o diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/pv/hypercall.c similarity index 84% copy from xen/arch/x86/hypercall.c copy to xen/arch/x86/pv/hypercall.c index c0718f8..5f5460a 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/pv/hypercall.c @@ -1,5 +1,7 @@ /****************************************************************************** - * arch/x86/hypercall.c + * arch/pv/hypercall.c + * + * PV hypercall dispatching routines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,66 +16,13 @@ * You should have received a copy of the GNU General Public License * along with this program; If not, see <http://www.gnu.org/licenses/>. * - * Copyright (c) 2015,2016 Citrix Systems Ltd. + * Copyright (c) 2017 Citrix Systems Ltd. */ #include <xen/compiler.h> #include <xen/hypercall.h> #include <xen/trace.h> -#define ARGS(x, n) \ - [ __HYPERVISOR_ ## x ] = { n, n } -#define COMP(x, n, c) \ - [ __HYPERVISOR_ ## x ] = { n, c } - -const hypercall_args_t hypercall_args_table[NR_hypercalls] = -{ - ARGS(set_trap_table, 1), - ARGS(mmu_update, 4), - ARGS(set_gdt, 2), - ARGS(stack_switch, 2), - COMP(set_callbacks, 3, 4), - ARGS(fpu_taskswitch, 1), - ARGS(sched_op_compat, 2), - ARGS(platform_op, 1), - ARGS(set_debugreg, 2), - ARGS(get_debugreg, 1), - COMP(update_descriptor, 2, 4), - ARGS(memory_op, 2), - ARGS(multicall, 2), - COMP(update_va_mapping, 3, 4), - COMP(set_timer_op, 1, 2), - ARGS(event_channel_op_compat, 1), - ARGS(xen_version, 2), - ARGS(console_io, 3), - ARGS(physdev_op_compat, 1), - ARGS(grant_table_op, 3), - ARGS(vm_assist, 2), - COMP(update_va_mapping_otherdomain, 4, 5), - ARGS(vcpu_op, 3), - COMP(set_segment_base, 2, 0), - ARGS(mmuext_op, 4), - ARGS(xsm_op, 1), - ARGS(nmi_op, 2), - ARGS(sched_op, 2), - ARGS(callback_op, 2), - ARGS(xenoprof_op, 2), - ARGS(event_channel_op, 2), - ARGS(physdev_op, 2), - ARGS(hvm_op, 2), - ARGS(sysctl, 1), - ARGS(domctl, 1), - ARGS(kexec_op, 2), - ARGS(tmem_op, 1), - ARGS(xenpmu_op, 2), - ARGS(dm_op, 3), - ARGS(mca, 1), - ARGS(arch_1, 1), -}; - -#undef COMP -#undef ARGS - #define HYPERCALL(x) \ [ __HYPERVISOR_ ## x ] = { (hypercall_fn_t *) do_ ## x, \ (hypercall_fn_t *) do_ ## x } -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |