77 */
88#include "kvm_util.h"
99#include "vmx.h"
10+ #include "svm_util.h"
1011#include "kselftest.h"
1112
1213
@@ -17,6 +18,28 @@ static void l2_guest_code(void)
1718 vmcall ();
1819}
1920
21+ static void l1_svm_code (struct svm_test_data * svm )
22+ {
23+ unsigned long l2_guest_stack [L2_GUEST_STACK_SIZE ];
24+ uintptr_t save_cr3 ;
25+
26+ generic_svm_setup (svm , l2_guest_code ,
27+ & l2_guest_stack [L2_GUEST_STACK_SIZE ]);
28+
29+ /* Try to run L2 with invalid CR3 and make sure it fails */
30+ save_cr3 = svm -> vmcb -> save .cr3 ;
31+ svm -> vmcb -> save .cr3 = -1ull ;
32+ run_guest (svm -> vmcb , svm -> vmcb_gpa );
33+ GUEST_ASSERT (svm -> vmcb -> control .exit_code == SVM_EXIT_ERR );
34+
35+ /* Now restore CR3 and make sure L2 runs successfully */
36+ svm -> vmcb -> save .cr3 = save_cr3 ;
37+ run_guest (svm -> vmcb , svm -> vmcb_gpa );
38+ GUEST_ASSERT (svm -> vmcb -> control .exit_code == SVM_EXIT_VMMCALL );
39+
40+ GUEST_DONE ();
41+ }
42+
2043static void l1_vmx_code (struct vmx_pages * vmx_pages )
2144{
2245 unsigned long l2_guest_stack [L2_GUEST_STACK_SIZE ];
@@ -43,16 +66,30 @@ static void l1_vmx_code(struct vmx_pages *vmx_pages)
4366 GUEST_DONE ();
4467}
4568
69+ static void l1_guest_code (void * data )
70+ {
71+ if (this_cpu_has (X86_FEATURE_VMX ))
72+ l1_vmx_code (data );
73+ else
74+ l1_svm_code (data );
75+ }
76+
4677int main (int argc , char * argv [])
4778{
4879 struct kvm_vcpu * vcpu ;
4980 struct kvm_vm * vm ;
5081 vm_vaddr_t guest_gva = 0 ;
5182
52- TEST_REQUIRE (kvm_cpu_has (X86_FEATURE_VMX ));
83+ TEST_REQUIRE (kvm_cpu_has (X86_FEATURE_VMX ) ||
84+ kvm_cpu_has (X86_FEATURE_SVM ));
85+
86+ vm = vm_create_with_one_vcpu (& vcpu , l1_guest_code );
87+
88+ if (kvm_cpu_has (X86_FEATURE_VMX ))
89+ vcpu_alloc_vmx (vm , & guest_gva );
90+ else
91+ vcpu_alloc_svm (vm , & guest_gva );
5392
54- vm = vm_create_with_one_vcpu (& vcpu , l1_vmx_code );
55- vcpu_alloc_vmx (vm , & guest_gva );
5693 vcpu_args_set (vcpu , 1 , guest_gva );
5794
5895 for (;;) {
0 commit comments