3
3
#include "kvm_util.h"
4
4
#include "processor.h"
5
5
#include "vmx.h"
6
+ #include "svm_util.h"
6
7
7
8
#include <string.h>
8
9
#include <sys/ioctl.h>
@@ -20,10 +21,11 @@ static void l2_guest_code(void)
20
21
: : [port ] "d" (ARBITRARY_IO_PORT ) : "rax" );
21
22
}
22
23
23
- void l1_guest_code (struct vmx_pages * vmx )
24
- {
25
24
#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
+ {
27
29
28
30
GUEST_ASSERT (vmx -> vmcs_gpa );
29
31
GUEST_ASSERT (prepare_for_vmx_operation (vmx ));
@@ -38,24 +40,53 @@ void l1_guest_code(struct vmx_pages *vmx)
38
40
GUEST_DONE ();
39
41
}
40
42
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
+
41
59
int main (void )
42
60
{
43
61
struct kvm_vcpu * vcpu ;
44
62
struct kvm_run * run ;
45
63
struct kvm_vcpu_events events ;
46
- vm_vaddr_t vmx_pages_gva ;
47
64
struct ucall uc ;
48
65
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 );
50
70
51
71
TEST_REQUIRE (kvm_has_cap (KVM_CAP_X86_TRIPLE_FAULT_EVENT ));
52
72
53
- vm = vm_create_with_one_vcpu (& vcpu , l1_guest_code );
54
- vm_enable_cap (vm , KVM_CAP_X86_TRIPLE_FAULT_EVENT , 1 );
55
73
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 );
56
89
run = vcpu -> run ;
57
- vcpu_alloc_vmx (vm , & vmx_pages_gva );
58
- vcpu_args_set (vcpu , 1 , vmx_pages_gva );
59
90
vcpu_run (vcpu );
60
91
61
92
TEST_ASSERT (run -> exit_reason == KVM_EXIT_IO ,
@@ -78,13 +109,21 @@ int main(void)
78
109
"No triple fault pending" );
79
110
vcpu_run (vcpu );
80
111
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
- }
89
112
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 ;
90
129
}
0 commit comments