KVM: selftests: Init IDT and exception handlers for all VMs/vCPUs on x86
authorSean Christopherson <seanjc@google.com>
Thu, 14 Mar 2024 23:26:29 +0000 (16:26 -0700)
committerSean Christopherson <seanjc@google.com>
Mon, 29 Apr 2024 19:55:15 +0000 (12:55 -0700)
Initialize the IDT and exception handlers for all non-barebones VMs and
vCPUs on x86.  Forcing tests to manually configure the IDT just to save
8KiB of memory is a terrible tradeoff, and also leads to weird tests
(multiple tests have deliberately relied on shutdown to indicate success),
and hard-to-debug failures, e.g. instead of a precise unexpected exception
failure, tests see only shutdown.

Reviewed-by: Ackerley Tng <ackerleytng@google.com>
Link: https://lore.kernel.org/r/20240314232637.2538648-11-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
23 files changed:
tools/testing/selftests/kvm/include/x86_64/processor.h
tools/testing/selftests/kvm/lib/x86_64/processor.c
tools/testing/selftests/kvm/x86_64/amx_test.c
tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c
tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c
tools/testing/selftests/kvm/x86_64/hyperv_features.c
tools/testing/selftests/kvm/x86_64/hyperv_ipi.c
tools/testing/selftests/kvm/x86_64/kvm_pv_test.c
tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c
tools/testing/selftests/kvm/x86_64/platform_info_test.c
tools/testing/selftests/kvm/x86_64/pmu_counters_test.c
tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c
tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c
tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c
tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c
tools/testing/selftests/kvm/x86_64/ucna_injection_test.c
tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c
tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c
tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c
tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c
tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c

index 2b654b65fe47eff62d620de35e3971788533fc68..8eb57de0b5876db37d79508f28d1cee3c205df1b 100644 (file)
@@ -1134,8 +1134,6 @@ struct idt_entry {
        uint32_t offset2; uint32_t reserved;
 };
 
-void vm_init_descriptor_tables(struct kvm_vm *vm);
-void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);
 void vm_install_exception_handler(struct kvm_vm *vm, int vector,
                        void (*handler)(struct ex_regs *));
 
index 88d6e6caa30211b62f9444703cedd6e259653465..f3d9ac7e86925587b51a057bc070fb4bb51ba705 100644 (file)
@@ -541,7 +541,7 @@ static void kvm_setup_tss_64bit(struct kvm_vm *vm, struct kvm_segment *segp,
        kvm_seg_fill_gdt_64bit(vm, segp);
 }
 
-void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu)
+static void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu)
 {
        struct kvm_vm *vm = vcpu->vm;
        struct kvm_sregs sregs;
@@ -586,6 +586,8 @@ static void vcpu_init_sregs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
 
        sregs.cr3 = vm->pgd;
        vcpu_sregs_set(vcpu, &sregs);
+
+       vcpu_init_descriptor_tables(vcpu);
 }
 
 static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
@@ -639,7 +641,7 @@ void route_exception(struct ex_regs *regs)
                     regs->vector, regs->rip);
 }
 
-void vm_init_descriptor_tables(struct kvm_vm *vm)
+static void vm_init_descriptor_tables(struct kvm_vm *vm)
 {
        extern void *idt_handlers;
        int i;
@@ -671,6 +673,8 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
 void kvm_arch_vm_post_create(struct kvm_vm *vm)
 {
        vm_create_irqchip(vm);
+       vm_init_descriptor_tables(vm);
+
        sync_global_to_guest(vm, host_cpu_is_intel);
        sync_global_to_guest(vm, host_cpu_is_amd);
        sync_global_to_guest(vm, is_forced_emulation_enabled);
index 8e5713e36d4b8a43b3e4c7c0871083c3c077e9b5..903940c54d2dec024a716d421f50b14b8f4f5b7d 100644 (file)
@@ -244,8 +244,6 @@ int main(int argc, char *argv[])
        vcpu_regs_get(vcpu, &regs1);
 
        /* Register #NM handler */
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
        vm_install_exception_handler(vm, NM_VECTOR, guest_nm_handler);
 
        /* amx cfg for guest_code */
index f3c2239228b10e3ba7cbfe9f8406cfbbe5f58825..762628f7d4ba38d93431023300edeeae540f801a 100644 (file)
@@ -110,8 +110,6 @@ static void test_fix_hypercall(struct kvm_vcpu *vcpu, bool disable_quirk)
 {
        struct kvm_vm *vm = vcpu->vm;
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
        vm_install_exception_handler(vcpu->vm, UD_VECTOR, guest_ud_handler);
 
        if (disable_quirk)
index 4f3f3a9b038b91d8fa86576d573bfc1609599c2b..e192720bfe14b4a1af8d55fabb90eea9cd6be92f 100644 (file)
@@ -257,8 +257,6 @@ int main(int argc, char *argv[])
        vcpu_args_set(vcpu, 3, vmx_pages_gva, hv_pages_gva, addr_gva2gpa(vm, hcall_page));
        vcpu_set_msr(vcpu, HV_X64_MSR_VP_INDEX, vcpu->id);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
        vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
        vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
 
index b923a285e96f9492108ac17c21a070a4dd4ffa61..068e9c69710d2e05f4561ddf4e49efc34e1b6e34 100644 (file)
@@ -156,9 +156,6 @@ static void guest_test_msrs_access(void)
                        vcpu_init_cpuid(vcpu, prev_cpuid);
                }
 
-               vm_init_descriptor_tables(vm);
-               vcpu_init_descriptor_tables(vcpu);
-
                /* TODO: Make this entire test easier to maintain. */
                if (stage >= 21)
                        vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
@@ -532,9 +529,6 @@ static void guest_test_hcalls_access(void)
        while (true) {
                vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
 
-               vm_init_descriptor_tables(vm);
-               vcpu_init_descriptor_tables(vcpu);
-
                /* Hypercall input/output */
                hcall_page = vm_vaddr_alloc_pages(vm, 2);
                memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
index 8206f5ef42dd114b7bc4e4df3ec962626e947e44..22c0c124582fd89785bc8acb66d4fc181e8c2852 100644 (file)
@@ -254,16 +254,13 @@ int main(int argc, char *argv[])
        hcall_page = vm_vaddr_alloc_pages(vm, 2);
        memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
 
-       vm_init_descriptor_tables(vm);
 
        vcpu[1] = vm_vcpu_add(vm, RECEIVER_VCPU_ID_1, receiver_code);
-       vcpu_init_descriptor_tables(vcpu[1]);
        vcpu_args_set(vcpu[1], 2, hcall_page, addr_gva2gpa(vm, hcall_page));
        vcpu_set_msr(vcpu[1], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_1);
        vcpu_set_hv_cpuid(vcpu[1]);
 
        vcpu[2] = vm_vcpu_add(vm, RECEIVER_VCPU_ID_2, receiver_code);
-       vcpu_init_descriptor_tables(vcpu[2]);
        vcpu_args_set(vcpu[2], 2, hcall_page, addr_gva2gpa(vm, hcall_page));
        vcpu_set_msr(vcpu[2], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_2);
        vcpu_set_hv_cpuid(vcpu[2]);
index 40cc59f4e6501316695485a10532479787899d81..78878b3a272522ddb85f97da1a7349d2064a1d4b 100644 (file)
@@ -183,9 +183,6 @@ int main(void)
 
        vcpu_clear_cpuid_entry(vcpu, KVM_CPUID_FEATURES);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        enter_guest(vcpu);
        kvm_vm_free(vm);
 
index 853802641e1eafe553bc7c0676801227a5601be9..9c8445379d76de509d9e47f900b120fb1280f636 100644 (file)
@@ -80,9 +80,6 @@ int main(int argc, char *argv[])
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
        vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_MWAIT);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        while (1) {
                vcpu_run(vcpu);
                TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
index cdca3579b3cdae7ec3e08e6a0640dc3464d2ae74..eda88080c1868f0d244db96c9be41952fe031f20 100644 (file)
@@ -49,9 +49,6 @@ int main(int argc, char *argv[])
 
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        msr_platform_info = vcpu_get_msr(vcpu, MSR_PLATFORM_INFO);
        vcpu_set_msr(vcpu, MSR_PLATFORM_INFO,
                     msr_platform_info | MSR_PLATFORM_INFO_MAX_TURBO_RATIO);
index bad2ab1b981069acf7ca365199e1112fc8cc28d3..2556777c4674604a0464289186b8090517154dab 100644 (file)
@@ -28,9 +28,6 @@ static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,
        struct kvm_vm *vm;
 
        vm = vm_create_with_one_vcpu(vcpu, guest_code);
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(*vcpu);
-
        sync_global_to_guest(vm, kvm_pmu_version);
 
        /*
index 5ce53b8c46e02b6dd0b90e1f9043ee86d1f23aca..26b3e7efe5ddc7a401591d332be489f23ba752d8 100644 (file)
@@ -334,9 +334,6 @@ static void test_pmu_config_disable(void (*guest_code)(void))
        vm_enable_cap(vm, KVM_CAP_PMU_CAPABILITY, KVM_PMU_CAP_DISABLE);
 
        vcpu = vm_vcpu_add(vm, 0, guest_code);
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        TEST_ASSERT(!sanity_check_pmu(vcpu),
                    "Guest should not be able to use disabled PMU.");
 
@@ -873,9 +870,6 @@ int main(int argc, char *argv[])
 
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        TEST_REQUIRE(sanity_check_pmu(vcpu));
 
        if (use_amd_pmu())
index 362be40fc00d0658a38cac7a761266222a56ec03..fabeeaddfb3acfe97616c1e45d085aa62a2ae867 100644 (file)
@@ -57,9 +57,6 @@ int main(int argc, char *argv[])
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
        vcpu_args_set(vcpu, 1, kvm_is_tdp_enabled());
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        vcpu_set_cpuid_property(vcpu, X86_PROPERTY_MAX_PHY_ADDR, MAXPHYADDR);
 
        rc = kvm_check_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE);
index 32bef39bec2178068238a2de650f87179acc22f6..916e04248fbbdd13c10a109fa89e515b9692d90f 100644 (file)
@@ -93,9 +93,6 @@ int main(int argc, char *argv[])
 
        vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        vm_install_exception_handler(vm, VINTR_IRQ_NUMBER, vintr_irq_handler);
        vm_install_exception_handler(vm, INTR_IRQ_NUMBER, intr_irq_handler);
 
index f4a1137e04abca41140ca2ef5a16f276426283f3..00135cbba35eacd98f34b4df3e4968a715228fdd 100644 (file)
@@ -48,9 +48,6 @@ int main(int argc, char *argv[])
        TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
 
        vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        vcpu_alloc_svm(vm, &svm_gva);
 
        vcpu_args_set(vcpu, 2, svm_gva, vm->arch.idt);
index 2478a9e507435832b98bb7f5d19fceb42168132b..7b6481d6c0d3db806be872fcee98663db65290ed 100644 (file)
@@ -152,9 +152,6 @@ static void run_test(bool is_nmi)
 
        vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
        vm_install_exception_handler(vm, BP_VECTOR, guest_bp_handler);
        vm_install_exception_handler(vm, INT_NR, guest_int_handler);
index fb976d6a1969c14f18dd6bb2b45e1b9603c6f7a0..57f157c06b393c98242c313600cc183b4f1fecae 100644 (file)
@@ -282,10 +282,6 @@ int main(int argc, char *argv[])
        cmcidis_vcpu = create_vcpu_with_mce_cap(vm, 1, false, cmci_disabled_guest_code);
        cmci_vcpu = create_vcpu_with_mce_cap(vm, 2, true, cmci_enabled_guest_code);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(ucna_vcpu);
-       vcpu_init_descriptor_tables(cmcidis_vcpu);
-       vcpu_init_descriptor_tables(cmci_vcpu);
        vm_install_exception_handler(vm, CMCI_VECTOR, guest_cmci_handler);
        vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
 
index af9981a6642f238214e10647dde7b1cf06065125..32b2794b78fece1172fbf44e63ff770e1507a965 100644 (file)
@@ -525,9 +525,6 @@ KVM_ONE_VCPU_TEST(user_msr, msr_filter_allow, guest_code_filter_allow)
 
        vm_ioctl(vm, KVM_X86_SET_MSR_FILTER, &filter_allow);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
 
        /* Process guest code userspace exits. */
index fad3634fd9eb62e34ded1c3f59b1d38a0b61d03a..3fd6eceab46f5d320e0f1a12206889e8a9dbf0a1 100644 (file)
@@ -115,9 +115,6 @@ int main(int argc, char *argv[])
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
        get_set_sigalrm_vcpu(vcpu);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
 
        /*
index 3b93f262b797c310d9da3d3dfebbcdab7fa79de9..7c92536551cca17a33fd40e0149b0e487a50023c 100644 (file)
@@ -85,9 +85,6 @@ KVM_ONE_VCPU_TEST(vmx_pmu_caps, guest_wrmsr_perf_capabilities, guest_code)
        struct ucall uc;
        int r, i;
 
-       vm_init_descriptor_tables(vcpu->vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
 
        vcpu_args_set(vcpu, 1, host_cap.capabilities);
index c78e5f7551165efe4392f5b13800c3dc29cc7370..a76078a08ff82f527e5b62d4e96234647c957a38 100644 (file)
@@ -408,8 +408,6 @@ int main(int argc, char *argv[])
 
        vm = vm_create_with_one_vcpu(&params[0].vcpu, halter_guest_code);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(params[0].vcpu);
        vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler);
 
        virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA);
index 25a0b0db5c3c9dfac6819de37e8c7d0a541935fb..95ce192d07530979602c09ad54f09611ddfc1022 100644 (file)
@@ -109,9 +109,6 @@ int main(int argc, char *argv[])
        vm = vm_create_with_one_vcpu(&vcpu, guest_code);
        run = vcpu->run;
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
-
        while (1) {
                vcpu_run(vcpu);
 
index 1ba06551526b1faef9fedbc05440b442f6d7b548..aa88cc541fe215ac90c582478e90a4fe422a3a6a 100644 (file)
@@ -554,8 +554,6 @@ int main(int argc, char *argv[])
        };
        vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &vec);
 
-       vm_init_descriptor_tables(vm);
-       vcpu_init_descriptor_tables(vcpu);
        vm_install_exception_handler(vm, EVTCHN_VECTOR, evtchn_handler);
 
        if (do_runstate_tests) {