[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86/hypercall: Split out PV hypercall infrastructure



commit 0c221ae9d745de138850c6903a5861e2582df863
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Feb 13 11:49:33 2017 +0000
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Thu Feb 16 14:15:25 2017 +0000

    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>
    Acked-by: 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 | 257 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 261 insertions(+), 224 deletions(-)

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/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c
new file mode 100644
index 0000000..9144f2e
--- /dev/null
+++ b/xen/arch/x86/pv/hypercall.c
@@ -0,0 +1,257 @@
+/******************************************************************************
+ * arch/x86/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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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) 2017 Citrix Systems Ltd.
+ */
+
+#include <xen/compiler.h>
+#include <xen/hypercall.h>
+#include <xen/trace.h>
+
+#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
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.