From bf10993313e909bbf928bc40fd03141ffe23c7ec Mon Sep 17 00:00:00 2001 From: Reiji Watanabe Date: Tue, 20 Dec 2022 09:09:21 -0800 Subject: [PATCH 01/12] KVM: selftests: kvm_vm_elf_load() and elfhdr_get() should close fd kvm_vm_elf_load() and elfhdr_get() open one file each, but they never close the opened file descriptor. If a test repeatedly creates and destroys a VM with __vm_create(), which (directly or indirectly) calls those two functions, the test might end up getting a open failure with EMFILE. Fix those two functions to close the file descriptor. Signed-off-by: Reiji Watanabe Reviewed-by: Oliver Upton Reviewed-by: Andrew Jones Reviewed-by: Sean Christopherson Link: https://lore.kernel.org/r/20221220170921.2499209-2-reijiw@google.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/lib/elf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/elf.c b/tools/testing/selftests/kvm/lib/elf.c index 820ac2d08c98..266f3876e10a 100644 --- a/tools/testing/selftests/kvm/lib/elf.c +++ b/tools/testing/selftests/kvm/lib/elf.c @@ -90,6 +90,7 @@ static void elfhdr_get(const char *filename, Elf64_Ehdr *hdrp) " hdrp->e_shentsize: %x\n" " expected: %zx", hdrp->e_shentsize, sizeof(Elf64_Shdr)); + close(fd); } /* VM ELF Load @@ -190,4 +191,5 @@ void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename) phdr.p_filesz); } } + close(fd); } From ca17899693518acde9ba1adcf46b95d76286106d Mon Sep 17 00:00:00 2001 From: Aaron Lewis Date: Fri, 9 Dec 2022 20:13:27 +0000 Subject: [PATCH 02/12] KVM: selftests: Fix a typo in the vcpu_msrs_set assert The assert incorrectly identifies the ioctl being called. Switch it from KVM_GET_MSRS to KVM_SET_MSRS. Fixes: 6ebfef83f03f ("KVM: selftest: Add proper helpers for x86-specific save/restore ioctls") Signed-off-by: Aaron Lewis Reviewed-by: Jim Mattson Reviewed-by: Sean Christopherson Link: https://lore.kernel.org/r/20221209201326.2781950-1-aaronlewis@google.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/include/x86_64/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 2a5f47d51388..bbe47e6707eb 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -717,7 +717,7 @@ static inline void vcpu_msrs_set(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs) int r = __vcpu_ioctl(vcpu, KVM_SET_MSRS, msrs); TEST_ASSERT(r == msrs->nmsrs, - "KVM_GET_MSRS failed, r: %i (failed on MSR %x)", + "KVM_SET_MSRS failed, r: %i (failed on MSR %x)", r, r < 0 || r >= msrs->nmsrs ? -1 : msrs->entries[r].index); } static inline void vcpu_debugregs_get(struct kvm_vcpu *vcpu, From e99b0d4cc2b679c5892d0994610b44e7b584d98b Mon Sep 17 00:00:00 2001 From: Vishal Annapurve Date: Wed, 11 Jan 2023 00:44:43 +0000 Subject: [PATCH 03/12] KVM: selftests: x86: Use "this_cpu" prefix for cpu vendor queries Replace is_intel/amd_cpu helpers with this_cpu_* helpers to better convey the intent of querying vendor of the current cpu. Suggested-by: Sean Christopherson Reviewed-by: David Matlack Signed-off-by: Vishal Annapurve Link: https://lore.kernel.org/r/20230111004445.416840-2-vannapurve@google.com Signed-off-by: Sean Christopherson --- .../selftests/kvm/include/x86_64/processor.h | 25 +++++++++++++++--- .../selftests/kvm/lib/x86_64/processor.c | 26 ++----------------- .../selftests/kvm/x86_64/fix_hypercall_test.c | 4 +-- .../selftests/kvm/x86_64/mmio_warning_test.c | 2 +- .../kvm/x86_64/pmu_event_filter_test.c | 4 +-- .../vmx_exception_with_invalid_guest_state.c | 2 +- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index bbe47e6707eb..b5ea72f79540 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -555,6 +555,28 @@ static inline uint32_t this_cpu_model(void) return x86_model(this_cpu_fms()); } +static inline bool this_cpu_vendor_string_is(const char *vendor) +{ + const uint32_t *chunk = (const uint32_t *)vendor; + uint32_t eax, ebx, ecx, edx; + + cpuid(0, &eax, &ebx, &ecx, &edx); + return (ebx == chunk[0] && edx == chunk[1] && ecx == chunk[2]); +} + +static inline bool this_cpu_is_intel(void) +{ + return this_cpu_vendor_string_is("GenuineIntel"); +} + +/* + * Exclude early K5 samples with a vendor string of "AMDisbetter!" + */ +static inline bool this_cpu_is_amd(void) +{ + return this_cpu_vendor_string_is("AuthenticAMD"); +} + static inline uint32_t __this_cpu_has(uint32_t function, uint32_t index, uint8_t reg, uint8_t lo, uint8_t hi) { @@ -691,9 +713,6 @@ static inline void cpu_relax(void) "hlt\n" \ ) -bool is_intel_cpu(void); -bool is_amd_cpu(void); - struct kvm_x86_state *vcpu_save_state(struct kvm_vcpu *vcpu); void vcpu_load_state(struct kvm_vcpu *vcpu, struct kvm_x86_state *state); void kvm_x86_state_cleanup(struct kvm_x86_state *state); diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index acfa1d01e7df..7d1768543b91 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -113,7 +113,7 @@ static void sregs_dump(FILE *stream, struct kvm_sregs *sregs, uint8_t indent) bool kvm_is_tdp_enabled(void) { - if (is_intel_cpu()) + if (this_cpu_is_intel()) return get_kvm_intel_param_bool("ept"); else return get_kvm_amd_param_bool("npt"); @@ -1006,28 +1006,6 @@ void kvm_x86_state_cleanup(struct kvm_x86_state *state) free(state); } -static bool cpu_vendor_string_is(const char *vendor) -{ - const uint32_t *chunk = (const uint32_t *)vendor; - uint32_t eax, ebx, ecx, edx; - - cpuid(0, &eax, &ebx, &ecx, &edx); - return (ebx == chunk[0] && edx == chunk[1] && ecx == chunk[2]); -} - -bool is_intel_cpu(void) -{ - return cpu_vendor_string_is("GenuineIntel"); -} - -/* - * Exclude early K5 samples with a vendor string of "AMDisbetter!" - */ -bool is_amd_cpu(void) -{ - return cpu_vendor_string_is("AuthenticAMD"); -} - void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits) { if (!kvm_cpu_has_p(X86_PROPERTY_MAX_PHY_ADDR)) { @@ -1236,7 +1214,7 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm) max_gfn = (1ULL << (vm->pa_bits - vm->page_shift)) - 1; /* Avoid reserved HyperTransport region on AMD processors. */ - if (!is_amd_cpu()) + if (!this_cpu_is_amd()) return max_gfn; /* On parts with <40 physical address bits, the area is fully hidden */ diff --git a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c b/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c index 32f7e09ef67c..5489c9836ec8 100644 --- a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c +++ b/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c @@ -48,10 +48,10 @@ static void guest_main(void) const uint8_t *other_hypercall_insn; uint64_t ret; - if (is_intel_cpu()) { + if (this_cpu_is_intel()) { native_hypercall_insn = vmx_vmcall; other_hypercall_insn = svm_vmmcall; - } else if (is_amd_cpu()) { + } else if (this_cpu_is_amd()) { native_hypercall_insn = svm_vmmcall; other_hypercall_insn = vmx_vmcall; } else { diff --git a/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c index fb02581953a3..b0a2a0bae0f3 100644 --- a/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c +++ b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c @@ -93,7 +93,7 @@ int main(void) { int warnings_before, warnings_after; - TEST_REQUIRE(is_intel_cpu()); + TEST_REQUIRE(this_cpu_is_intel()); TEST_REQUIRE(!vm_is_unrestricted_guest(NULL)); diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c index 2de98fce7edd..c728822461b2 100644 --- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c +++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c @@ -363,7 +363,7 @@ static void test_pmu_config_disable(void (*guest_code)(void)) */ static bool use_intel_pmu(void) { - return is_intel_cpu() && + return this_cpu_is_intel() && kvm_cpu_property(X86_PROPERTY_PMU_VERSION) && kvm_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS) && kvm_pmu_has(X86_PMU_FEATURE_BRANCH_INSNS_RETIRED); @@ -397,7 +397,7 @@ static bool use_amd_pmu(void) uint32_t family = kvm_cpu_family(); uint32_t model = kvm_cpu_model(); - return is_amd_cpu() && + return this_cpu_is_amd() && (is_zen1(family, model) || is_zen2(family, model) || is_zen3(family, model)); diff --git a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c b/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c index 2641b286b4ed..53e1ef2fc774 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c @@ -111,7 +111,7 @@ int main(int argc, char *argv[]) struct kvm_vcpu *vcpu; struct kvm_vm *vm; - TEST_REQUIRE(is_intel_cpu()); + TEST_REQUIRE(this_cpu_is_intel()); TEST_REQUIRE(!vm_is_unrestricted_guest(NULL)); vm = vm_create_with_one_vcpu(&vcpu, guest_code); From e6df2ae3f57c6bfab29e767796ce8d4796a84ebb Mon Sep 17 00:00:00 2001 From: Vishal Annapurve Date: Wed, 11 Jan 2023 00:44:44 +0000 Subject: [PATCH 04/12] KVM: selftests: x86: Cache host CPU vendor (AMD vs. Intel) Cache the host CPU vendor for userspace and share it with guest code. All the current callers of this_cpu* actually care about host cpu so they are updated to check host_cpu_is*. Suggested-by: Sean Christopherson Reviewed-by: David Matlack Signed-off-by: Vishal Annapurve Link: https://lore.kernel.org/r/20230111004445.416840-3-vannapurve@google.com Signed-off-by: Sean Christopherson --- .../selftests/kvm/include/x86_64/processor.h | 3 +++ tools/testing/selftests/kvm/lib/x86_64/processor.c | 14 ++++++++++++-- .../selftests/kvm/x86_64/fix_hypercall_test.c | 4 ++-- .../selftests/kvm/x86_64/mmio_warning_test.c | 2 +- .../selftests/kvm/x86_64/pmu_event_filter_test.c | 4 ++-- .../vmx_exception_with_invalid_guest_state.c | 2 +- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index b5ea72f79540..53ffa43c90db 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -19,6 +19,9 @@ #include "../kvm_util.h" +extern bool host_cpu_is_intel; +extern bool host_cpu_is_amd; + #define NMI_VECTOR 0x02 #define X86_EFLAGS_FIXED (1u << 1) diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index 7d1768543b91..84915bc7d689 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -19,6 +19,8 @@ #define MAX_NR_CPUID_ENTRIES 100 vm_vaddr_t exception_handlers; +bool host_cpu_is_amd; +bool host_cpu_is_intel; static void regs_dump(FILE *stream, struct kvm_regs *regs, uint8_t indent) { @@ -113,7 +115,7 @@ static void sregs_dump(FILE *stream, struct kvm_sregs *sregs, uint8_t indent) bool kvm_is_tdp_enabled(void) { - if (this_cpu_is_intel()) + if (host_cpu_is_intel) return get_kvm_intel_param_bool("ept"); else return get_kvm_amd_param_bool("npt"); @@ -555,6 +557,8 @@ static void vcpu_setup(struct kvm_vm *vm, struct kvm_vcpu *vcpu) void kvm_arch_vm_post_create(struct kvm_vm *vm) { vm_create_irqchip(vm); + sync_global_to_guest(vm, host_cpu_is_intel); + sync_global_to_guest(vm, host_cpu_is_amd); } struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id, @@ -1214,7 +1218,7 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm) max_gfn = (1ULL << (vm->pa_bits - vm->page_shift)) - 1; /* Avoid reserved HyperTransport region on AMD processors. */ - if (!this_cpu_is_amd()) + if (!host_cpu_is_amd) return max_gfn; /* On parts with <40 physical address bits, the area is fully hidden */ @@ -1254,3 +1258,9 @@ bool vm_is_unrestricted_guest(struct kvm_vm *vm) return get_kvm_intel_param_bool("unrestricted_guest"); } + +void kvm_selftest_arch_init(void) +{ + host_cpu_is_intel = this_cpu_is_intel(); + host_cpu_is_amd = this_cpu_is_amd(); +} diff --git a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c b/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c index 5489c9836ec8..0f728f05ea82 100644 --- a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c +++ b/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c @@ -48,10 +48,10 @@ static void guest_main(void) const uint8_t *other_hypercall_insn; uint64_t ret; - if (this_cpu_is_intel()) { + if (host_cpu_is_intel) { native_hypercall_insn = vmx_vmcall; other_hypercall_insn = svm_vmmcall; - } else if (this_cpu_is_amd()) { + } else if (host_cpu_is_amd) { native_hypercall_insn = svm_vmmcall; other_hypercall_insn = vmx_vmcall; } else { diff --git a/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c index b0a2a0bae0f3..ce1ccc4c1503 100644 --- a/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c +++ b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c @@ -93,7 +93,7 @@ int main(void) { int warnings_before, warnings_after; - TEST_REQUIRE(this_cpu_is_intel()); + TEST_REQUIRE(host_cpu_is_intel); TEST_REQUIRE(!vm_is_unrestricted_guest(NULL)); diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c index c728822461b2..4dbb454e1760 100644 --- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c +++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c @@ -363,7 +363,7 @@ static void test_pmu_config_disable(void (*guest_code)(void)) */ static bool use_intel_pmu(void) { - return this_cpu_is_intel() && + return host_cpu_is_intel && kvm_cpu_property(X86_PROPERTY_PMU_VERSION) && kvm_cpu_property(X86_PROPERTY_PMU_NR_GP_COUNTERS) && kvm_pmu_has(X86_PMU_FEATURE_BRANCH_INSNS_RETIRED); @@ -397,7 +397,7 @@ static bool use_amd_pmu(void) uint32_t family = kvm_cpu_family(); uint32_t model = kvm_cpu_model(); - return this_cpu_is_amd() && + return host_cpu_is_amd && (is_zen1(family, model) || is_zen2(family, model) || is_zen3(family, model)); diff --git a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c b/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c index 53e1ef2fc774..ccdfa5dc1a4d 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c @@ -111,7 +111,7 @@ int main(int argc, char *argv[]) struct kvm_vcpu *vcpu; struct kvm_vm *vm; - TEST_REQUIRE(this_cpu_is_intel()); + TEST_REQUIRE(host_cpu_is_intel); TEST_REQUIRE(!vm_is_unrestricted_guest(NULL)); vm = vm_create_with_one_vcpu(&vcpu, guest_code); From ea25ace7710b918fe49647350d4dee363563908f Mon Sep 17 00:00:00 2001 From: Vishal Annapurve Date: Wed, 11 Jan 2023 00:44:45 +0000 Subject: [PATCH 05/12] KVM: selftests: x86: Use host's native hypercall instruction in kvm_hypercall() Use the host CPU's native hypercall instruction, i.e. VMCALL vs. VMMCALL, in kvm_hypercall(), as relying on KVM to patch in the native hypercall on a #UD for the "wrong" hypercall requires KVM_X86_QUIRK_FIX_HYPERCALL_INSN to be enabled and flat out doesn't work if guest memory is encrypted with a private key, e.g. for SEV VMs. Suggested-by: Sean Christopherson Reviewed-by: David Matlack Signed-off-by: Vishal Annapurve Link: https://lore.kernel.org/r/20230111004445.416840-4-vannapurve@google.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/lib/x86_64/processor.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index 84915bc7d689..ae1e573d94ce 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -1144,9 +1144,15 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2, { uint64_t r; - asm volatile("vmcall" + asm volatile("test %[use_vmmcall], %[use_vmmcall]\n\t" + "jnz 1f\n\t" + "vmcall\n\t" + "jmp 2f\n\t" + "1: vmmcall\n\t" + "2:" : "=a"(r) - : "a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3)); + : "a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3), + [use_vmmcall] "r" (host_cpu_is_amd)); return r; } From 96e78ebbe8e47d096c1ed74ec1d28a107126c26c Mon Sep 17 00:00:00 2001 From: zhang songyi Date: Mon, 19 Dec 2022 14:32:27 +0800 Subject: [PATCH 06/12] KVM: x86/xen: Remove unneeded semicolon The semicolon after the "}" is unneeded. Signed-off-by: zhang songyi Link: https://lore.kernel.org/r/202212191432274558936@zte.com.cn Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c b/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c index dae510c263b4..6a838df69174 100644 --- a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c +++ b/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c @@ -426,7 +426,7 @@ static void *juggle_shinfo_state(void *arg) __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_init); __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_destroy); pthread_testcancel(); - }; + } return NULL; } From 78332517a5dab54514ae719805eec218715de1fc Mon Sep 17 00:00:00 2001 From: Jing Zhang Date: Tue, 17 Jan 2023 14:27:07 -0800 Subject: [PATCH 07/12] KVM: selftests: Stop assuming stats are contiguous in kvm_binary_stats_test Remove the assumption from kvm_binary_stats_test that all stats are laid out contiguously in memory. The current stats in KVM are contiguously laid out in memory, but that may change in the future and the ABI specifically allows holes in the stats data (since each stat exposes its own offset). While here drop the check that each stats' offset is less than size_data, as that is now always true by construction. Link: https://lore.kernel.org/kvm/20221208193857.4090582-9-dmatlack@google.com/ Fixes: 0b45d58738cd ("KVM: selftests: Add selftest for KVM statistics data binary interface") Signed-off-by: Jing Zhang [dmatlack: Re-worded the commit message.] Signed-off-by: David Matlack Link: https://lore.kernel.org/r/20230117222707.3949974-1-dmatlack@google.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/kvm_binary_stats_test.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c index 894417c96f70..a7001e29dc06 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -134,7 +134,7 @@ static void stats_test(int stats_fd) "Bucket size of stats (%s) is not zero", pdesc->name); } - size_data += pdesc->size * sizeof(*stats_data); + size_data = max(size_data, pdesc->offset + pdesc->size * sizeof(*stats_data)); } /* @@ -149,14 +149,6 @@ static void stats_test(int stats_fd) TEST_ASSERT(size_data >= header.num_desc * sizeof(*stats_data), "Data size is not correct"); - /* Check stats offset */ - for (i = 0; i < header.num_desc; ++i) { - pdesc = get_stats_descriptor(stats_desc, i, &header); - TEST_ASSERT(pdesc->offset < size_data, - "Invalid offset (%u) for stats: %s", - pdesc->offset, pdesc->name); - } - /* Allocate memory for stats data */ stats_data = malloc(size_data); TEST_ASSERT(stats_data, "Allocate memory for stats data"); From e5b426879fc39063d940902adbf38d5485925304 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 18 Jan 2023 17:21:32 +0800 Subject: [PATCH 08/12] KVM: selftests: Remove duplicate VM creation in memslot_perf_test Remove a spurious call to __vm_create_with_one_vcpu() that was introduced by a merge gone sideways. Fixes: eb5618911af0 ("Merge tag 'kvmarm-6.2' of https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD") Signed-off-by: Gavin Shan Reviewed-by: Maciej S. Szmigiero Link: https://lore.kernel.org/r/20230118092133.320003-2-gshan@redhat.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/memslot_perf_test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/testing/selftests/kvm/memslot_perf_test.c b/tools/testing/selftests/kvm/memslot_perf_test.c index e6587e193490..adbbcca3e354 100644 --- a/tools/testing/selftests/kvm/memslot_perf_test.c +++ b/tools/testing/selftests/kvm/memslot_perf_test.c @@ -308,8 +308,6 @@ static bool prepare_vm(struct vm_data *data, int nslots, uint64_t *maxslots, data->hva_slots = malloc(sizeof(*data->hva_slots) * data->nslots); TEST_ASSERT(data->hva_slots, "malloc() fail"); - data->vm = __vm_create_with_one_vcpu(&data->vcpu, mempages, guest_code); - pr_info_v("Adding slots 1..%i, each slot with %"PRIu64" pages + %"PRIu64" extra pages last\n", data->nslots, data->pages_per_slot, rempages); From 45f679550d7295b52a1cd8b7afaf2bd31453a5b0 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 18 Jan 2023 17:21:33 +0800 Subject: [PATCH 09/12] KVM: selftests: Assign guest page size in sync area early in memslot_perf_test The guest page size in the synchronization area is needed by all test cases. So it's reasonable to set it in the unified preparation function (prepare_vm()). Signed-off-by: Gavin Shan Reviewed-by: Maciej S. Szmigiero Link: https://lore.kernel.org/r/20230118092133.320003-3-gshan@redhat.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/memslot_perf_test.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/memslot_perf_test.c b/tools/testing/selftests/kvm/memslot_perf_test.c index adbbcca3e354..4210cd21d159 100644 --- a/tools/testing/selftests/kvm/memslot_perf_test.c +++ b/tools/testing/selftests/kvm/memslot_perf_test.c @@ -347,6 +347,7 @@ static bool prepare_vm(struct vm_data *data, int nslots, uint64_t *maxslots, virt_map(data->vm, MEM_GPA, MEM_GPA, data->npages); sync = (typeof(sync))vm_gpa2hva(data, MEM_SYNC_GPA, NULL); + sync->guest_page_size = data->vm->page_size; atomic_init(&sync->start_flag, false); atomic_init(&sync->exit_flag, false); atomic_init(&sync->sync_flag, false); @@ -808,8 +809,6 @@ static bool test_execute(int nslots, uint64_t *maxslots, } sync = (typeof(sync))vm_gpa2hva(data, MEM_SYNC_GPA, NULL); - - sync->guest_page_size = data->vm->page_size; if (tdata->prepare && !tdata->prepare(data, sync, maxslots)) { ret = false; From 7ae69d7087a9a4d014e11b5328a49091cc1682f8 Mon Sep 17 00:00:00 2001 From: Shaoqin Huang Date: Thu, 2 Feb 2023 10:57:15 +0800 Subject: [PATCH 10/12] selftests: KVM: Replace optarg with arg in guest_modes_cmdline The parameter arg in guest_modes_cmdline not being used now, and the optarg should be replaced with arg in guest_modes_cmdline. And this is the chance to change strtoul() to atoi_non_negative(), since guest mode ID will never be negative. Signed-off-by: Shaoqin Huang Fixes: e42ac777d661 ("KVM: selftests: Factor out guest mode code") Reviewed-by: Andrew Jones Reviewed-by: Vipin Sharma Link: https://lore.kernel.org/r/20230202025716.216323-1-shahuang@redhat.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/lib/guest_modes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/lib/guest_modes.c b/tools/testing/selftests/kvm/lib/guest_modes.c index 99a575bbbc52..1df3ce4b16fd 100644 --- a/tools/testing/selftests/kvm/lib/guest_modes.c +++ b/tools/testing/selftests/kvm/lib/guest_modes.c @@ -127,7 +127,7 @@ void guest_modes_cmdline(const char *arg) mode_selected = true; } - mode = strtoul(optarg, NULL, 10); + mode = atoi_non_negative("Guest mode ID", arg); TEST_ASSERT(mode < NUM_VM_MODES, "Guest mode ID %d too big", mode); guest_modes[mode].enabled = true; } From 6c77ae716d546d71b21f0c9ee7d405314a3f3f9e Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Mon, 6 Feb 2023 21:24:30 +0100 Subject: [PATCH 11/12] KVM: selftests: Clean up misnomers in xen_shinfo_test As discussed[*], relabel the poorly named structs to align with the current KVM nomenclature. Old names are a leftover from before commit 52491a38b2c2 ("KVM: Initialize gfn_to_pfn_cache locks in dedicated helper"), which i.a. introduced kvm_gpc_init() and renamed kvm_gfn_to_pfn_cache_init()/ _destroy() to kvm_gpc_activate()/_deactivate(). Partly in an effort to avoid implying that the cache really is destroyed/freed. While at it, get rid of #define GPA_INVALID, which being used as a GFN, is not only misnamed, but also unnecessarily reinvents a UAPI constant. No functional change intended. [*] https://lore.kernel.org/r/Y5yZ6CFkEMBqyJ6v@google.com Signed-off-by: Michal Luczaj Link: https://lore.kernel.org/r/20230206202430.1898057-1-mhal@rbox.co Signed-off-by: Sean Christopherson --- .../testing/selftests/kvm/x86_64/xen_shinfo_test.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c b/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c index 6a838df69174..fd39a15d6970 100644 --- a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c +++ b/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c @@ -19,9 +19,6 @@ #include -/* Defined in include/linux/kvm_types.h */ -#define GPA_INVALID (~(ulong)0) - #define SHINFO_REGION_GVA 0xc0000000ULL #define SHINFO_REGION_GPA 0xc0000000ULL #define SHINFO_REGION_SLOT 10 @@ -412,19 +409,19 @@ static void *juggle_shinfo_state(void *arg) { struct kvm_vm *vm = (struct kvm_vm *)arg; - struct kvm_xen_hvm_attr cache_init = { + struct kvm_xen_hvm_attr cache_activate = { .type = KVM_XEN_ATTR_TYPE_SHARED_INFO, .u.shared_info.gfn = SHINFO_REGION_GPA / PAGE_SIZE }; - struct kvm_xen_hvm_attr cache_destroy = { + struct kvm_xen_hvm_attr cache_deactivate = { .type = KVM_XEN_ATTR_TYPE_SHARED_INFO, - .u.shared_info.gfn = GPA_INVALID + .u.shared_info.gfn = KVM_XEN_INVALID_GFN }; for (;;) { - __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_init); - __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_destroy); + __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_activate); + __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_deactivate); pthread_testcancel(); } From 695fa5a64cf52ab1aa2c89c93bbb1fd08995304a Mon Sep 17 00:00:00 2001 From: Shaoqin Huang Date: Wed, 8 Feb 2023 15:18:00 +0800 Subject: [PATCH 12/12] KVM: selftests: Remove duplicate macro definition The KVM_GUEST_PAGE_TABLE_MIN_PADDR macro has been defined in include/kvm_util_base.h. So remove the duplicate definition in lib/kvm_util.c. Fixes: cce0c23dd944 ("KVM: selftests: Add wrapper to allocate page table page") Signed-off-by: Shaoqin Huang Link: https://lore.kernel.org/r/20230208071801.68620-1-shahuang@redhat.com Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/lib/kvm_util.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 56d5ea949cbb..a3648c3f273f 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1941,9 +1941,6 @@ vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min, return vm_phy_pages_alloc(vm, 1, paddr_min, memslot); } -/* Arbitrary minimum physical address used for virtual translation tables. */ -#define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000 - vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm) { return vm_phy_page_alloc(vm, KVM_GUEST_PAGE_TABLE_MIN_PADDR,