1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * svm_nested_shutdown_test 4 * 5 * Copyright (C) 2022, Red Hat, Inc. 6 * 7 * Nested SVM testing: test that unintercepted shutdown in L2 doesn't crash the host 8 */ 9 10 #include "test_util.h" 11 #include "kvm_util.h" 12 #include "processor.h" 13 #include "svm_util.h" 14 15 static void l2_guest_code(struct svm_test_data *svm) 16 { 17 __asm__ __volatile__("ud2"); 18 } 19 20 static void l1_guest_code(struct svm_test_data *svm, struct idt_entry *idt) 21 { 22 struct vmcb *vmcb = svm->vmcb; 23 24 generic_svm_setup(svm, l2_guest_code); 25 26 vmcb->control.intercept &= ~(BIT(INTERCEPT_SHUTDOWN)); 27 28 idt[6].p = 0; // #UD is intercepted but its injection will cause #NP 29 idt[11].p = 0; // #NP is not intercepted and will cause another 30 // #NP that will be converted to #DF 31 idt[8].p = 0; // #DF will cause #NP which will cause SHUTDOWN 32 33 run_guest(vmcb, svm->vmcb_gpa); 34 35 /* should not reach here */ 36 GUEST_ASSERT(0); 37 } 38 39 int main(int argc, char *argv[]) 40 { 41 struct kvm_vcpu *vcpu; 42 gva_t svm_gva; 43 struct kvm_vm *vm; 44 45 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM)); 46 47 vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code); 48 vcpu_alloc_svm(vm, &svm_gva); 49 50 vcpu_args_set(vcpu, 2, svm_gva, vm->arch.idt); 51 52 vcpu_run(vcpu); 53 TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN); 54 55 kvm_vm_free(vm); 56 } 57