Commit c1b9793b authored by Sean Christopherson's avatar Sean Christopherson

KVM: selftests: Init IDT and exception handlers for all VMs/vCPUs on x86

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: default avatarAckerley Tng <ackerleytng@google.com>
Link: https://lore.kernel.org/r/20240314232637.2538648-11-seanjc@google.comSigned-off-by: default avatarSean Christopherson <seanjc@google.com>
parent d8c63805
...@@ -1134,8 +1134,6 @@ struct idt_entry { ...@@ -1134,8 +1134,6 @@ struct idt_entry {
uint32_t offset2; uint32_t reserved; 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 vm_install_exception_handler(struct kvm_vm *vm, int vector,
void (*handler)(struct ex_regs *)); void (*handler)(struct ex_regs *));
......
...@@ -541,7 +541,7 @@ static void kvm_setup_tss_64bit(struct kvm_vm *vm, struct kvm_segment *segp, ...@@ -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); 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_vm *vm = vcpu->vm;
struct kvm_sregs sregs; struct kvm_sregs sregs;
...@@ -586,6 +586,8 @@ static void vcpu_init_sregs(struct kvm_vm *vm, struct kvm_vcpu *vcpu) ...@@ -586,6 +586,8 @@ static void vcpu_init_sregs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
sregs.cr3 = vm->pgd; sregs.cr3 = vm->pgd;
vcpu_sregs_set(vcpu, &sregs); vcpu_sregs_set(vcpu, &sregs);
vcpu_init_descriptor_tables(vcpu);
} }
static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr, 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) ...@@ -639,7 +641,7 @@ void route_exception(struct ex_regs *regs)
regs->vector, regs->rip); 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; extern void *idt_handlers;
int i; int i;
...@@ -671,6 +673,8 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcpu) ...@@ -671,6 +673,8 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
void kvm_arch_vm_post_create(struct kvm_vm *vm) void kvm_arch_vm_post_create(struct kvm_vm *vm)
{ {
vm_create_irqchip(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_intel);
sync_global_to_guest(vm, host_cpu_is_amd); sync_global_to_guest(vm, host_cpu_is_amd);
sync_global_to_guest(vm, is_forced_emulation_enabled); sync_global_to_guest(vm, is_forced_emulation_enabled);
......
...@@ -244,8 +244,6 @@ int main(int argc, char *argv[]) ...@@ -244,8 +244,6 @@ int main(int argc, char *argv[])
vcpu_regs_get(vcpu, &regs1); vcpu_regs_get(vcpu, &regs1);
/* Register #NM handler */ /* Register #NM handler */
vm_init_descriptor_tables(vm);
vcpu_init_descriptor_tables(vcpu);
vm_install_exception_handler(vm, NM_VECTOR, guest_nm_handler); vm_install_exception_handler(vm, NM_VECTOR, guest_nm_handler);
/* amx cfg for guest_code */ /* amx cfg for guest_code */
......
...@@ -110,8 +110,6 @@ static void test_fix_hypercall(struct kvm_vcpu *vcpu, bool disable_quirk) ...@@ -110,8 +110,6 @@ static void test_fix_hypercall(struct kvm_vcpu *vcpu, bool disable_quirk)
{ {
struct kvm_vm *vm = vcpu->vm; 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); vm_install_exception_handler(vcpu->vm, UD_VECTOR, guest_ud_handler);
if (disable_quirk) if (disable_quirk)
......
...@@ -257,8 +257,6 @@ int main(int argc, char *argv[]) ...@@ -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_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); 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, UD_VECTOR, guest_ud_handler);
vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler); vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
......
...@@ -156,9 +156,6 @@ static void guest_test_msrs_access(void) ...@@ -156,9 +156,6 @@ static void guest_test_msrs_access(void)
vcpu_init_cpuid(vcpu, prev_cpuid); vcpu_init_cpuid(vcpu, prev_cpuid);
} }
vm_init_descriptor_tables(vm);
vcpu_init_descriptor_tables(vcpu);
/* TODO: Make this entire test easier to maintain. */ /* TODO: Make this entire test easier to maintain. */
if (stage >= 21) if (stage >= 21)
vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0); vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
...@@ -532,9 +529,6 @@ static void guest_test_hcalls_access(void) ...@@ -532,9 +529,6 @@ static void guest_test_hcalls_access(void)
while (true) { while (true) {
vm = vm_create_with_one_vcpu(&vcpu, guest_hcall); vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
vm_init_descriptor_tables(vm);
vcpu_init_descriptor_tables(vcpu);
/* Hypercall input/output */ /* Hypercall input/output */
hcall_page = vm_vaddr_alloc_pages(vm, 2); hcall_page = vm_vaddr_alloc_pages(vm, 2);
memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize()); memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
......
...@@ -254,16 +254,13 @@ int main(int argc, char *argv[]) ...@@ -254,16 +254,13 @@ int main(int argc, char *argv[])
hcall_page = vm_vaddr_alloc_pages(vm, 2); hcall_page = vm_vaddr_alloc_pages(vm, 2);
memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize()); 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[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_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_msr(vcpu[1], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_1);
vcpu_set_hv_cpuid(vcpu[1]); vcpu_set_hv_cpuid(vcpu[1]);
vcpu[2] = vm_vcpu_add(vm, RECEIVER_VCPU_ID_2, receiver_code); 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_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_msr(vcpu[2], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_2);
vcpu_set_hv_cpuid(vcpu[2]); vcpu_set_hv_cpuid(vcpu[2]);
......
...@@ -183,9 +183,6 @@ int main(void) ...@@ -183,9 +183,6 @@ int main(void)
vcpu_clear_cpuid_entry(vcpu, KVM_CPUID_FEATURES); vcpu_clear_cpuid_entry(vcpu, KVM_CPUID_FEATURES);
vm_init_descriptor_tables(vm);
vcpu_init_descriptor_tables(vcpu);
enter_guest(vcpu); enter_guest(vcpu);
kvm_vm_free(vm); kvm_vm_free(vm);
......
...@@ -80,9 +80,6 @@ int main(int argc, char *argv[]) ...@@ -80,9 +80,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&vcpu, guest_code); vm = vm_create_with_one_vcpu(&vcpu, guest_code);
vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_MWAIT); vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_MWAIT);
vm_init_descriptor_tables(vm);
vcpu_init_descriptor_tables(vcpu);
while (1) { while (1) {
vcpu_run(vcpu); vcpu_run(vcpu);
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
......
...@@ -49,9 +49,6 @@ int main(int argc, char *argv[]) ...@@ -49,9 +49,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&vcpu, guest_code); 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); msr_platform_info = vcpu_get_msr(vcpu, MSR_PLATFORM_INFO);
vcpu_set_msr(vcpu, MSR_PLATFORM_INFO, vcpu_set_msr(vcpu, MSR_PLATFORM_INFO,
msr_platform_info | MSR_PLATFORM_INFO_MAX_TURBO_RATIO); msr_platform_info | MSR_PLATFORM_INFO_MAX_TURBO_RATIO);
......
...@@ -28,9 +28,6 @@ static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, ...@@ -28,9 +28,6 @@ static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,
struct kvm_vm *vm; struct kvm_vm *vm;
vm = vm_create_with_one_vcpu(vcpu, guest_code); 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); sync_global_to_guest(vm, kvm_pmu_version);
/* /*
......
...@@ -334,9 +334,6 @@ static void test_pmu_config_disable(void (*guest_code)(void)) ...@@ -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); vm_enable_cap(vm, KVM_CAP_PMU_CAPABILITY, KVM_PMU_CAP_DISABLE);
vcpu = vm_vcpu_add(vm, 0, guest_code); vcpu = vm_vcpu_add(vm, 0, guest_code);
vm_init_descriptor_tables(vm);
vcpu_init_descriptor_tables(vcpu);
TEST_ASSERT(!sanity_check_pmu(vcpu), TEST_ASSERT(!sanity_check_pmu(vcpu),
"Guest should not be able to use disabled PMU."); "Guest should not be able to use disabled PMU.");
...@@ -873,9 +870,6 @@ int main(int argc, char *argv[]) ...@@ -873,9 +870,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&vcpu, guest_code); 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)); TEST_REQUIRE(sanity_check_pmu(vcpu));
if (use_amd_pmu()) if (use_amd_pmu())
......
...@@ -57,9 +57,6 @@ int main(int argc, char *argv[]) ...@@ -57,9 +57,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&vcpu, guest_code); vm = vm_create_with_one_vcpu(&vcpu, guest_code);
vcpu_args_set(vcpu, 1, kvm_is_tdp_enabled()); 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); vcpu_set_cpuid_property(vcpu, X86_PROPERTY_MAX_PHY_ADDR, MAXPHYADDR);
rc = kvm_check_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE); rc = kvm_check_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE);
......
...@@ -93,9 +93,6 @@ int main(int argc, char *argv[]) ...@@ -93,9 +93,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code); 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, VINTR_IRQ_NUMBER, vintr_irq_handler);
vm_install_exception_handler(vm, INTR_IRQ_NUMBER, intr_irq_handler); vm_install_exception_handler(vm, INTR_IRQ_NUMBER, intr_irq_handler);
......
...@@ -48,9 +48,6 @@ int main(int argc, char *argv[]) ...@@ -48,9 +48,6 @@ int main(int argc, char *argv[])
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code); 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_alloc_svm(vm, &svm_gva);
vcpu_args_set(vcpu, 2, svm_gva, vm->arch.idt); vcpu_args_set(vcpu, 2, svm_gva, vm->arch.idt);
......
...@@ -152,9 +152,6 @@ static void run_test(bool is_nmi) ...@@ -152,9 +152,6 @@ static void run_test(bool is_nmi)
vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code); 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, NMI_VECTOR, guest_nmi_handler);
vm_install_exception_handler(vm, BP_VECTOR, guest_bp_handler); vm_install_exception_handler(vm, BP_VECTOR, guest_bp_handler);
vm_install_exception_handler(vm, INT_NR, guest_int_handler); vm_install_exception_handler(vm, INT_NR, guest_int_handler);
......
...@@ -282,10 +282,6 @@ int main(int argc, char *argv[]) ...@@ -282,10 +282,6 @@ int main(int argc, char *argv[])
cmcidis_vcpu = create_vcpu_with_mce_cap(vm, 1, false, cmci_disabled_guest_code); 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); 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, CMCI_VECTOR, guest_cmci_handler);
vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler); vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
......
...@@ -525,9 +525,6 @@ KVM_ONE_VCPU_TEST(user_msr, msr_filter_allow, guest_code_filter_allow) ...@@ -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_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); vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
/* Process guest code userspace exits. */ /* Process guest code userspace exits. */
......
...@@ -115,9 +115,6 @@ int main(int argc, char *argv[]) ...@@ -115,9 +115,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&vcpu, guest_code); vm = vm_create_with_one_vcpu(&vcpu, guest_code);
get_set_sigalrm_vcpu(vcpu); 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); vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
/* /*
......
...@@ -85,9 +85,6 @@ KVM_ONE_VCPU_TEST(vmx_pmu_caps, guest_wrmsr_perf_capabilities, guest_code) ...@@ -85,9 +85,6 @@ KVM_ONE_VCPU_TEST(vmx_pmu_caps, guest_wrmsr_perf_capabilities, guest_code)
struct ucall uc; struct ucall uc;
int r, i; 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_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
vcpu_args_set(vcpu, 1, host_cap.capabilities); vcpu_args_set(vcpu, 1, host_cap.capabilities);
......
...@@ -408,8 +408,6 @@ int main(int argc, char *argv[]) ...@@ -408,8 +408,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&params[0].vcpu, halter_guest_code); 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); vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler);
virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA);
......
...@@ -109,9 +109,6 @@ int main(int argc, char *argv[]) ...@@ -109,9 +109,6 @@ int main(int argc, char *argv[])
vm = vm_create_with_one_vcpu(&vcpu, guest_code); vm = vm_create_with_one_vcpu(&vcpu, guest_code);
run = vcpu->run; run = vcpu->run;
vm_init_descriptor_tables(vm);
vcpu_init_descriptor_tables(vcpu);
while (1) { while (1) {
vcpu_run(vcpu); vcpu_run(vcpu);
......
...@@ -554,8 +554,6 @@ int main(int argc, char *argv[]) ...@@ -554,8 +554,6 @@ int main(int argc, char *argv[])
}; };
vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &vec); 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); vm_install_exception_handler(vm, EVTCHN_VECTOR, evtchn_handler);
if (do_runstate_tests) { if (do_runstate_tests) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment