]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
x86/xen: make hypercall_page generic
authorAnkur Arora <ankur.a.arora@oracle.com>
Thu, 29 Nov 2018 02:54:39 +0000 (18:54 -0800)
committerJoao Martins <joao.m.martins@oracle.com>
Wed, 20 Feb 2019 17:30:52 +0000 (12:30 -0500)
Export hypercall_page as a generic interface which can be implemented
by other hypervisors. With this change, hypercall_page now points to
the newly introduced xen_hypercall_page which is seeded by Xen, or to
one that is filled in by a different hypervisor.

Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
arch/x86/include/asm/xen/hypercall.h
arch/x86/xen/enlighten.c
arch/x86/xen/enlighten_hvm.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/enlighten_pvh.c
arch/x86/xen/xen-asm_32.S
arch/x86/xen/xen-asm_64.S
arch/x86/xen/xen-head.S

index ef05bea7010de473c4a73f5d99a1f74af2327ebc..1a3cd6680e6fda28d5de461699a642eaf20cc570 100644 (file)
@@ -86,11 +86,13 @@ struct xen_dm_op_buf;
  * there aren't more than 5 arguments...)
  */
 
-extern struct { char _entry[32]; } hypercall_page[];
+struct hypercall_entry { char _entry[32]; };
+extern struct hypercall_entry xen_hypercall_page[128];
+extern struct hypercall_entry *hypercall_page;
 
-#define __HYPERCALL            "call hypercall_page+%c[offset]"
+#define __HYPERCALL    CALL_NOSPEC
 #define __HYPERCALL_ENTRY(x)                                           \
-       [offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0]))
+       [thunk_target] "0" (hypercall_page + __HYPERVISOR_##x)
 
 #ifdef CONFIG_X86_32
 #define __HYPERCALL_RETREG     "eax"
@@ -116,7 +118,7 @@ extern struct { char _entry[32]; } hypercall_page[];
        register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \
        register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5;
 
-#define __HYPERCALL_0PARAM     "=r" (__res), ASM_CALL_CONSTRAINT
+#define __HYPERCALL_0PARAM     "=&r" (__res), ASM_CALL_CONSTRAINT
 #define __HYPERCALL_1PARAM     __HYPERCALL_0PARAM, "+r" (__arg1)
 #define __HYPERCALL_2PARAM     __HYPERCALL_1PARAM, "+r" (__arg2)
 #define __HYPERCALL_3PARAM     __HYPERCALL_2PARAM, "+r" (__arg3)
@@ -208,7 +210,7 @@ xen_single_call(unsigned int call,
 
        asm volatile(CALL_NOSPEC
                     : __HYPERCALL_5PARAM
-                    : [thunk_target] "a" (&hypercall_page[call])
+                    : [thunk_target] "0" (hypercall_page + call)
                     : __HYPERCALL_CLOBBER5);
 
        return (long)__res;
index 73b9736e89d2eb19d93735fc71a650504046338e..b36a10e6b5d7e6dc92aa79d05f081ad9db3653de 100644 (file)
@@ -20,6 +20,7 @@
 #include "smp.h"
 #include "pmu.h"
 
+struct hypercall_entry *hypercall_page;
 EXPORT_SYMBOL_GPL(hypercall_page);
 
 /*
index 0e75642d42a358ac3d23d8ccc932f255e833ecc8..40845e3e9a96255c5dd2a773d7f63a499b86173b 100644 (file)
@@ -105,8 +105,9 @@ static void __init init_hvm_pv_info(void)
 
                pv_info.name = "Xen HVM";
                msr = cpuid_ebx(base + 2);
-               pfn = __pa(hypercall_page);
+               pfn = __pa(xen_hypercall_page);
                wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
+               hypercall_page = xen_hypercall_page;
        }
 
        xen_setup_features();
index c54a493e139a78e37eab27cc36556396303a390e..e1537713b57d29d9e5570dd246cdf9dbe7a1de30 100644 (file)
@@ -1197,6 +1197,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
        if (!xen_start_info)
                return;
+       hypercall_page = xen_hypercall_page;
 
        xen_domain_type = XEN_PV_DOMAIN;
        xen_start_flags = xen_start_info->flags;
index 35b7599d2d0be8df7b8c355c62791b00e3c33871..d57a8ad1769e61cd30cc05d3883747cbb9d373de 100644 (file)
@@ -30,8 +30,9 @@ void __init xen_pvh_init(void)
        xen_start_flags = pvh_start_info.flags;
 
        msr = cpuid_ebx(xen_cpuid_base() + 2);
-       pfn = __pa(hypercall_page);
+       pfn = __pa(xen_hypercall_page);
        wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
+       hypercall_page = xen_hypercall_page;
 }
 
 void __init mem_map_via_hcall(struct boot_params *boot_params_p)
index c15db060a2425e45cded5b40e6363ebf29696cd6..ee4998055ea9a6d9f23ab6410be7bcd1b22e6104 100644 (file)
@@ -121,7 +121,7 @@ xen_iret_end_crit:
 
 hyper_iret:
        /* put this out of line since its very rarely used */
-       jmp hypercall_page + __HYPERVISOR_iret * 32
+       jmp xen_hypercall_page + __HYPERVISOR_iret * 32
 
        .globl xen_iret_start_crit, xen_iret_end_crit
 
index 1e9ef0ba30a582d841226708a695da6a098fb5fc..2172d6aec9a3df56b138f7ee00eb238aff8e296b 100644 (file)
@@ -70,7 +70,7 @@ ENTRY(xen_early_idt_handler_array)
 END(xen_early_idt_handler_array)
        __FINIT
 
-hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
+hypercall_iret = xen_hypercall_page + __HYPERVISOR_iret * 32
 /*
  * Xen64 iret frame:
  *
index 5077ead5e59cad4b4fc1db004237a746bf6ca960..7ff5437bd83ffe7bfaf15d7a47ab8630af7c38ca 100644 (file)
@@ -58,18 +58,18 @@ END(startup_xen)
 
 .pushsection .text
        .balign PAGE_SIZE
-ENTRY(hypercall_page)
+ENTRY(xen_hypercall_page)
        .rept (PAGE_SIZE / 32)
                UNWIND_HINT_EMPTY
                .skip 32
        .endr
 
 #define HYPERCALL(n) \
-       .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
+       .equ xen_hypercall_##n, xen_hypercall_page + __HYPERVISOR_##n * 32; \
        .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
 #include <asm/xen-hypercalls.h>
 #undef HYPERCALL
-END(hypercall_page)
+END(xen_hypercall_page)
 .popsection
 
        ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
@@ -85,7 +85,7 @@ END(hypercall_page)
 #ifdef CONFIG_XEN_PV
        ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          _ASM_PTR startup_xen)
 #endif
-       ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page)
+       ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR xen_hypercall_page)
        ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,
                .ascii "!writable_page_tables|pae_pgdir_above_4gb")
        ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,