|
[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 |