xref: /linux/tools/testing/selftests/kvm/x86/svm_nested_clear_efer_svme.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
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