diff options
Diffstat (limited to 'tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c')
| -rw-r--r-- | tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c | 81 |
1 files changed, 25 insertions, 56 deletions
diff --git a/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c b/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c index c542cc4762b1..dc9d40830a7f 100644 --- a/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c +++ b/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c @@ -61,14 +61,14 @@ struct hv_tlb_flush_ex { * - GVAs of the test pages' PTEs */ struct test_data { - vm_vaddr_t hcall_gva; - vm_paddr_t hcall_gpa; - vm_vaddr_t test_pages; - vm_vaddr_t test_pages_pte[NTEST_PAGES]; + gva_t hcall_gva; + gpa_t hcall_gpa; + gva_t test_pages; + gva_t test_pages_pte[NTEST_PAGES]; }; /* 'Worker' vCPU code checking the contents of the test page */ -static void worker_guest_code(vm_vaddr_t test_data) +static void worker_guest_code(gva_t test_data) { struct test_data *data = (struct test_data *)test_data; u32 vcpu_id = rdmsr(HV_X64_MSR_VP_INDEX); @@ -133,23 +133,12 @@ static void set_expected_val(void *addr, u64 val, int vcpu_id) * Update PTEs swapping two test pages. * TODO: use swap()/xchg() when these are provided. */ -static void swap_two_test_pages(vm_paddr_t pte_gva1, vm_paddr_t pte_gva2) +static void swap_two_test_pages(gpa_t pte_gva1, gpa_t pte_gva2) { - uint64_t tmp = *(uint64_t *)pte_gva1; + u64 tmp = *(u64 *)pte_gva1; - *(uint64_t *)pte_gva1 = *(uint64_t *)pte_gva2; - *(uint64_t *)pte_gva2 = tmp; -} - -/* - * TODO: replace the silly NOP loop with a proper udelay() implementation. - */ -static inline void do_delay(void) -{ - int i; - - for (i = 0; i < 1000000; i++) - asm volatile("nop"); + *(u64 *)pte_gva1 = *(u64 *)pte_gva2; + *(u64 *)pte_gva2 = tmp; } /* @@ -169,7 +158,7 @@ static inline void prepare_to_test(struct test_data *data) wmb(); /* Make sure workers have enough time to notice */ - do_delay(); + udelay(100); /* Swap test page mappings */ swap_two_test_pages(data->test_pages_pte[0], data->test_pages_pte[1]); @@ -189,19 +178,19 @@ static inline void post_test(struct test_data *data, u64 exp1, u64 exp2) set_expected_val((void *)data->test_pages, exp2, WORKER_VCPU_ID_2); /* Make sure workers have enough time to test */ - do_delay(); + udelay(100); } #define TESTVAL1 0x0101010101010101 #define TESTVAL2 0x0202020202020202 /* Main vCPU doing the test */ -static void sender_guest_code(vm_vaddr_t test_data) +static void sender_guest_code(gva_t test_data) { struct test_data *data = (struct test_data *)test_data; struct hv_tlb_flush *flush = (struct hv_tlb_flush *)data->hcall_gva; struct hv_tlb_flush_ex *flush_ex = (struct hv_tlb_flush_ex *)data->hcall_gva; - vm_paddr_t hcall_gpa = data->hcall_gpa; + gpa_t hcall_gpa = data->hcall_gpa; int i, stage = 1; wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID); @@ -559,45 +548,28 @@ static void *vcpu_thread(void *arg) return NULL; } -static void cancel_join_vcpu_thread(pthread_t thread, struct kvm_vcpu *vcpu) -{ - void *retval; - int r; - - r = pthread_cancel(thread); - TEST_ASSERT(!r, "pthread_cancel on vcpu_id=%d failed with errno=%d", - vcpu->id, r); - - r = pthread_join(thread, &retval); - TEST_ASSERT(!r, "pthread_join on vcpu_id=%d failed with errno=%d", - vcpu->id, r); - TEST_ASSERT(retval == PTHREAD_CANCELED, - "expected retval=%p, got %p", PTHREAD_CANCELED, - retval); -} - int main(int argc, char *argv[]) { struct kvm_vm *vm; struct kvm_vcpu *vcpu[3]; pthread_t threads[2]; - vm_vaddr_t test_data_page, gva; - vm_paddr_t gpa; - uint64_t *pte; + gva_t test_data_page, gva; + gpa_t gpa; + u64 *pte; struct test_data *data; struct ucall uc; - int stage = 1, r, i; + int stage = 1, i; TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_TLBFLUSH)); vm = vm_create_with_one_vcpu(&vcpu[0], sender_guest_code); /* Test data page */ - test_data_page = vm_vaddr_alloc_page(vm); + test_data_page = vm_alloc_page(vm); data = (struct test_data *)addr_gva2hva(vm, test_data_page); /* Hypercall input/output */ - data->hcall_gva = vm_vaddr_alloc_pages(vm, 2); + data->hcall_gva = vm_alloc_pages(vm, 2); data->hcall_gpa = addr_gva2gpa(vm, data->hcall_gva); memset(addr_gva2hva(vm, data->hcall_gva), 0x0, 2 * PAGE_SIZE); @@ -606,7 +578,7 @@ int main(int argc, char *argv[]) * and the test will swap their mappings. The third page keeps the indication * about the current state of mappings. */ - data->test_pages = vm_vaddr_alloc_pages(vm, NTEST_PAGES + 1); + data->test_pages = vm_alloc_pages(vm, NTEST_PAGES + 1); for (i = 0; i < NTEST_PAGES; i++) memset(addr_gva2hva(vm, data->test_pages + PAGE_SIZE * i), (u8)(i + 1), PAGE_SIZE); @@ -617,7 +589,7 @@ int main(int argc, char *argv[]) * Get PTE pointers for test pages and map them inside the guest. * Use separate page for each PTE for simplicity. */ - gva = vm_vaddr_unused_gap(vm, NTEST_PAGES * PAGE_SIZE, KVM_UTIL_MIN_VADDR); + gva = vm_unused_gva_gap(vm, NTEST_PAGES * PAGE_SIZE, KVM_UTIL_MIN_VADDR); for (i = 0; i < NTEST_PAGES; i++) { pte = vm_get_pte(vm, data->test_pages + i * PAGE_SIZE); gpa = addr_hva2gpa(vm, pte); @@ -643,11 +615,8 @@ int main(int argc, char *argv[]) vcpu_set_msr(vcpu[2], HV_X64_MSR_VP_INDEX, WORKER_VCPU_ID_2); vcpu_set_hv_cpuid(vcpu[2]); - r = pthread_create(&threads[0], NULL, vcpu_thread, vcpu[1]); - TEST_ASSERT(!r, "pthread_create() failed"); - - r = pthread_create(&threads[1], NULL, vcpu_thread, vcpu[2]); - TEST_ASSERT(!r, "pthread_create() failed"); + kvm_pthread_create(&threads[0], NULL, vcpu_thread, vcpu[1]); + kvm_pthread_create(&threads[1], NULL, vcpu_thread, vcpu[2]); while (true) { vcpu_run(vcpu[0]); @@ -672,8 +641,8 @@ int main(int argc, char *argv[]) } done: - cancel_join_vcpu_thread(threads[0], vcpu[1]); - cancel_join_vcpu_thread(threads[1], vcpu[2]); + kvm_pthread_cancel_join_async(threads[0]); + kvm_pthread_cancel_join_async(threads[1]); kvm_vm_free(vm); return 0; |
