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 15static void l2_guest_code(struct svm_test_data *svm) 16{ 17 __asm__ __volatile__("ud2"); 18} 19 20static void l1_guest_code(struct svm_test_data *svm, struct idt_entry *idt) 21{ 22 #define L2_GUEST_STACK_SIZE 64 23 unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; 24 struct vmcb *vmcb = svm->vmcb; 25 26 generic_svm_setup(svm, l2_guest_code, 27 &l2_guest_stack[L2_GUEST_STACK_SIZE]); 28 29 vmcb->control.intercept &= ~(BIT(INTERCEPT_SHUTDOWN)); 30 31 idt[6].p = 0; // #UD is intercepted but its injection will cause #NP 32 idt[11].p = 0; // #NP is not intercepted and will cause another 33 // #NP that will be converted to #DF 34 idt[8].p = 0; // #DF will cause #NP which will cause SHUTDOWN 35 36 run_guest(vmcb, svm->vmcb_gpa); 37 38 /* should not reach here */ 39 GUEST_ASSERT(0); 40} 41 42int main(int argc, char *argv[]) 43{ 44 struct kvm_vcpu *vcpu; 45 vm_vaddr_t svm_gva; 46 struct kvm_vm *vm; 47 48 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM)); 49 50 vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code); 51 vm_init_descriptor_tables(vm); 52 vcpu_init_descriptor_tables(vcpu); 53 54 vcpu_alloc_svm(vm, &svm_gva); 55 56 vcpu_args_set(vcpu, 2, svm_gva, vm->idt); 57 58 vcpu_run(vcpu); 59 TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN); 60 61 kvm_vm_free(vm); 62} 63