33#include "kvm_util.h"
44#include "processor.h"
55#include "vmx.h"
6+ #include "svm_util.h"
67
78#include <string.h>
89#include <sys/ioctl.h>
@@ -20,10 +21,11 @@ static void l2_guest_code(void)
2021 : : [port ] "d" (ARBITRARY_IO_PORT ) : "rax" );
2122}
2223
23- void l1_guest_code (struct vmx_pages * vmx )
24- {
2524#define L2_GUEST_STACK_SIZE 64
26- unsigned long l2_guest_stack [L2_GUEST_STACK_SIZE ];
25+ unsigned long l2_guest_stack [L2_GUEST_STACK_SIZE ];
26+
27+ void l1_guest_code_vmx (struct vmx_pages * vmx )
28+ {
2729
2830 GUEST_ASSERT (vmx -> vmcs_gpa );
2931 GUEST_ASSERT (prepare_for_vmx_operation (vmx ));
@@ -38,24 +40,53 @@ void l1_guest_code(struct vmx_pages *vmx)
3840 GUEST_DONE ();
3941}
4042
43+ void l1_guest_code_svm (struct svm_test_data * svm )
44+ {
45+ struct vmcb * vmcb = svm -> vmcb ;
46+
47+ generic_svm_setup (svm , l2_guest_code ,
48+ & l2_guest_stack [L2_GUEST_STACK_SIZE ]);
49+
50+ /* don't intercept shutdown to test the case of SVM allowing to do so */
51+ vmcb -> control .intercept &= ~(BIT (INTERCEPT_SHUTDOWN ));
52+
53+ run_guest (vmcb , svm -> vmcb_gpa );
54+
55+ /* should not reach here, L1 should crash */
56+ GUEST_ASSERT (0 );
57+ }
58+
4159int main (void )
4260{
4361 struct kvm_vcpu * vcpu ;
4462 struct kvm_run * run ;
4563 struct kvm_vcpu_events events ;
46- vm_vaddr_t vmx_pages_gva ;
4764 struct ucall uc ;
4865
49- TEST_REQUIRE (kvm_cpu_has (X86_FEATURE_VMX ));
66+ bool has_vmx = kvm_cpu_has (X86_FEATURE_VMX );
67+ bool has_svm = kvm_cpu_has (X86_FEATURE_SVM );
68+
69+ TEST_REQUIRE (has_vmx || has_svm );
5070
5171 TEST_REQUIRE (kvm_has_cap (KVM_CAP_X86_TRIPLE_FAULT_EVENT ));
5272
53- vm = vm_create_with_one_vcpu (& vcpu , l1_guest_code );
54- vm_enable_cap (vm , KVM_CAP_X86_TRIPLE_FAULT_EVENT , 1 );
5573
74+ if (has_vmx ) {
75+ vm_vaddr_t vmx_pages_gva ;
76+
77+ vm = vm_create_with_one_vcpu (& vcpu , l1_guest_code_vmx );
78+ vcpu_alloc_vmx (vm , & vmx_pages_gva );
79+ vcpu_args_set (vcpu , 1 , vmx_pages_gva );
80+ } else {
81+ vm_vaddr_t svm_gva ;
82+
83+ vm = vm_create_with_one_vcpu (& vcpu , l1_guest_code_svm );
84+ vcpu_alloc_svm (vm , & svm_gva );
85+ vcpu_args_set (vcpu , 1 , svm_gva );
86+ }
87+
88+ vm_enable_cap (vm , KVM_CAP_X86_TRIPLE_FAULT_EVENT , 1 );
5689 run = vcpu -> run ;
57- vcpu_alloc_vmx (vm , & vmx_pages_gva );
58- vcpu_args_set (vcpu , 1 , vmx_pages_gva );
5990 vcpu_run (vcpu );
6091
6192 TEST_ASSERT (run -> exit_reason == KVM_EXIT_IO ,
@@ -78,13 +109,21 @@ int main(void)
78109 "No triple fault pending" );
79110 vcpu_run (vcpu );
80111
81- switch (get_ucall (vcpu , & uc )) {
82- case UCALL_DONE :
83- break ;
84- case UCALL_ABORT :
85- REPORT_GUEST_ASSERT (uc );
86- default :
87- TEST_FAIL ("Unexpected ucall: %lu" , uc .cmd );
88- }
89112
113+ if (has_svm ) {
114+ TEST_ASSERT (run -> exit_reason == KVM_EXIT_SHUTDOWN ,
115+ "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n" ,
116+ run -> exit_reason ,
117+ exit_reason_str (run -> exit_reason ));
118+ } else {
119+ switch (get_ucall (vcpu , & uc )) {
120+ case UCALL_DONE :
121+ break ;
122+ case UCALL_ABORT :
123+ REPORT_GUEST_ASSERT (uc );
124+ default :
125+ TEST_FAIL ("Unexpected ucall: %lu" , uc .cmd );
126+ }
127+ }
128+ return 0 ;
90129}
0 commit comments