Some future tests that we are about to write need to perform hypercalls; move do_hypercall() and hypercall page setup methods to a more accessible location: libs/x86/hyperv.c. Signed-off-by: Siddharth Chandrasekaran <sidcha@xxxxxxxxx> --- lib/x86/hyperv.h | 4 +++ lib/x86/hyperv.c | 51 ++++++++++++++++++++++++++++++++++ x86/hyperv_connections.c | 60 ++++------------------------------------ 3 files changed, 60 insertions(+), 55 deletions(-) diff --git a/lib/x86/hyperv.h b/lib/x86/hyperv.h index 38de0d2..889f5a6 100644 --- a/lib/x86/hyperv.h +++ b/lib/x86/hyperv.h @@ -213,4 +213,8 @@ struct hv_reference_tsc_page { int64_t tsc_offset; }; +void hv_setup_hypercall(void); +void hv_teardown_hypercall(void); +u64 hv_hypercall(u16 code, u64 arg, bool fast); + #endif diff --git a/lib/x86/hyperv.c b/lib/x86/hyperv.c index 60f7645..e7c3351 100644 --- a/lib/x86/hyperv.c +++ b/lib/x86/hyperv.c @@ -1,6 +1,7 @@ #include "hyperv.h" #include "asm/io.h" #include "smp.h" +#include "alloc_page.h" enum { HV_TEST_DEV_SINT_ROUTE_CREATE = 1, @@ -68,3 +69,53 @@ void evt_conn_destroy(u8 sint, u8 conn_id) sint_disable(sint); synic_ctl(HV_TEST_DEV_EVT_CONN_DESTROY, 0, 0, conn_id); } + +static void *hypercall_page; + +void hv_setup_hypercall(void) +{ + u64 guestid = (0x8f00ull << 48); + + hypercall_page = alloc_page(); + if (!hypercall_page) + report_abort("failed to allocate hypercall page"); + + wrmsr(HV_X64_MSR_GUEST_OS_ID, guestid); + + wrmsr(HV_X64_MSR_HYPERCALL, + (u64)virt_to_phys(hypercall_page) | HV_X64_MSR_HYPERCALL_ENABLE); +} + +void hv_teardown_hypercall(void) +{ + wrmsr(HV_X64_MSR_HYPERCALL, 0); + wrmsr(HV_X64_MSR_GUEST_OS_ID, 0); + free_page(hypercall_page); +} + +u64 hv_hypercall(u16 code, u64 arg, bool fast) +{ + u64 ret; + u64 ctl = code; + if (fast) + ctl |= HV_HYPERCALL_FAST; + + asm volatile ("call *%[hcall_page]" +#ifdef __x86_64__ + "\n mov $0,%%r8" + : "=a"(ret) + : "c"(ctl), "d"(arg), +#else + : "=A"(ret) + : "A"(ctl), + "b" ((u32)(arg >> 32)), "c" ((u32)arg), + "D"(0), "S"(0), +#endif + [hcall_page] "m" (hypercall_page) +#ifdef __x86_64__ + : "r8" +#endif + ); + + return ret; +} diff --git a/x86/hyperv_connections.c b/x86/hyperv_connections.c index 6e8ac32..1650f01 100644 --- a/x86/hyperv_connections.c +++ b/x86/hyperv_connections.c @@ -38,56 +38,6 @@ static void sint_isr(isr_regs_t *regs) atomic_inc(&hv_vcpus[smp_id()].sint_received); } -static void *hypercall_page; - -static void setup_hypercall(void) -{ - u64 guestid = (0x8f00ull << 48); - - hypercall_page = alloc_page(); - if (!hypercall_page) - report_abort("failed to allocate hypercall page"); - - wrmsr(HV_X64_MSR_GUEST_OS_ID, guestid); - - wrmsr(HV_X64_MSR_HYPERCALL, - (u64)virt_to_phys(hypercall_page) | HV_X64_MSR_HYPERCALL_ENABLE); -} - -static void teardown_hypercall(void) -{ - wrmsr(HV_X64_MSR_HYPERCALL, 0); - wrmsr(HV_X64_MSR_GUEST_OS_ID, 0); - free_page(hypercall_page); -} - -static u64 do_hypercall(u16 code, u64 arg, bool fast) -{ - u64 ret; - u64 ctl = code; - if (fast) - ctl |= HV_HYPERCALL_FAST; - - asm volatile ("call *%[hcall_page]" -#ifdef __x86_64__ - "\n mov $0,%%r8" - : "=a"(ret) - : "c"(ctl), "d"(arg), -#else - : "=A"(ret) - : "A"(ctl), - "b" ((u32)(arg >> 32)), "c" ((u32)arg), - "D"(0), "S"(0), -#endif - [hcall_page] "m" (hypercall_page) -#ifdef __x86_64__ - : "r8" -#endif - ); - - return ret; -} - static void setup_cpu(void *ctx) { int vcpu; @@ -147,7 +97,7 @@ static void do_msg(void *ctx) msg->payload[0]++; atomic_set(&hv->sint_received, 0); - hv->hvcall_status = do_hypercall(HVCALL_POST_MESSAGE, + hv->hvcall_status = hv_hypercall(HVCALL_POST_MESSAGE, virt_to_phys(msg), 0); atomic_inc(&ncpus_done); } @@ -200,7 +150,7 @@ static void do_evt(void *ctx) struct hv_vcpu *hv = &hv_vcpus[vcpu]; atomic_set(&hv->sint_received, 0); - hv->hvcall_status = do_hypercall(HVCALL_SIGNAL_EVENT, + hv->hvcall_status = hv_hypercall(HVCALL_SIGNAL_EVENT, hv->evt_conn, 1); atomic_inc(&ncpus_done); } @@ -279,9 +229,9 @@ int main(int ac, char **av) handle_irq(MSG_VEC, sint_isr); handle_irq(EVT_VEC, sint_isr); - setup_hypercall(); + hv_setup_hypercall(); - if (do_hypercall(HVCALL_SIGNAL_EVENT, 0x1234, 1) == + if (hv_hypercall(HVCALL_SIGNAL_EVENT, 0x1234, 1) == HV_STATUS_INVALID_HYPERCALL_CODE) { report_skip("Hyper-V SynIC connections are not supported"); goto summary; @@ -325,7 +275,7 @@ int main(int ac, char **av) for (i = 0; i < ncpus; i++) on_cpu(i, teardown_cpu, NULL); - teardown_hypercall(); + hv_teardown_hypercall(); summary: return report_summary(); -- 2.17.1 Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B Sitz: Berlin Ust-ID: DE 289 237 879