1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2026, Google LLC. 4 */ 5 #include "kvm_util.h" 6 #include "vmx.h" 7 #include "svm_util.h" 8 #include "kselftest.h" 9 10 11 static void l2_guest_code(void) 12 { 13 unsigned long efer = rdmsr(MSR_EFER); 14 15 /* generic_svm_setup() initializes EFER_SVME set for L2 */ 16 GUEST_ASSERT(efer & EFER_SVME); 17 wrmsr(MSR_EFER, efer & ~EFER_SVME); 18 19 /* Unreachable, L1 should be shutdown */ 20 GUEST_ASSERT(0); 21 } 22 23 static void l1_guest_code(struct svm_test_data *svm) 24 { 25 generic_svm_setup(svm, l2_guest_code); 26 run_guest(svm->vmcb, svm->vmcb_gpa); 27 28 /* Unreachable, L1 should be shutdown */ 29 GUEST_ASSERT(0); 30 } 31 32 int main(int argc, char *argv[]) 33 { 34 struct kvm_vcpu *vcpu; 35 struct kvm_vm *vm; 36 gva_t nested_gva = 0; 37 38 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM)); 39 40 vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code); 41 42 vcpu_alloc_svm(vm, &nested_gva); 43 vcpu_args_set(vcpu, 1, nested_gva); 44 45 vcpu_run(vcpu); 46 TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN); 47 48 kvm_vm_free(vm); 49 return 0; 50 } 51