Skip to content

Commit 8357b9e

Browse files
Maxim Levitskybonzini
authored andcommitted
KVM: selftests: add svm part to triple_fault_test
Add a SVM implementation to triple_fault_test to test that emulated/injected shutdown works. Since instead of the VMX, the SVM allows the hypervisor to avoid intercepting shutdown in guest, don't intercept shutdown to test that KVM suports this correctly. Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Message-Id: <20221103141351.50662-9-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 92e7d5c commit 8357b9e

File tree

1 file changed

+56
-17
lines changed

1 file changed

+56
-17
lines changed

tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
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+
4159
int 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

Comments
 (0)