Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: selftests: Add SEV-ES shutdown test

Regression test for ae20eef5 ("KVM: SVM: Update SEV-ES shutdown intercepts
with more metadata"). Test confirms userspace is correctly indicated of
a guest shutdown not previous behavior of an EINVAL from KVM_RUN.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Alper Gun <alpergun@google.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Cc: kvm@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Signed-off-by: Peter Gonda <pgonda@google.com>
Tested-by: Pratik R. Sampat <pratikrajesh.sampat@amd.com>
Link: https://lore.kernel.org/r/20240709182936.146487-1-pgonda@google.com
[sean: clobber IDT to ensure #UD leads to SHUTDOWN]
Signed-off-by: Sean Christopherson <seanjc@google.com>

authored by

Peter Gonda and committed by
Sean Christopherson
2f6fcfa1 c0d1a39d

+32
+32
tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
··· 160 160 kvm_vm_free(vm); 161 161 } 162 162 163 + static void guest_shutdown_code(void) 164 + { 165 + struct desc_ptr idt; 166 + 167 + /* Clobber the IDT so that #UD is guaranteed to trigger SHUTDOWN. */ 168 + memset(&idt, 0, sizeof(idt)); 169 + __asm__ __volatile__("lidt %0" :: "m"(idt)); 170 + 171 + __asm__ __volatile__("ud2"); 172 + } 173 + 174 + static void test_sev_es_shutdown(void) 175 + { 176 + struct kvm_vcpu *vcpu; 177 + struct kvm_vm *vm; 178 + 179 + uint32_t type = KVM_X86_SEV_ES_VM; 180 + 181 + vm = vm_sev_create_with_one_vcpu(type, guest_shutdown_code, &vcpu); 182 + 183 + vm_sev_launch(vm, SEV_POLICY_ES, NULL); 184 + 185 + vcpu_run(vcpu); 186 + TEST_ASSERT(vcpu->run->exit_reason == KVM_EXIT_SHUTDOWN, 187 + "Wanted SHUTDOWN, got %s", 188 + exit_reason_str(vcpu->run->exit_reason)); 189 + 190 + kvm_vm_free(vm); 191 + } 192 + 163 193 int main(int argc, char *argv[]) 164 194 { 165 195 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); ··· 200 170 if (kvm_cpu_has(X86_FEATURE_SEV_ES)) { 201 171 test_sev(guest_sev_es_code, SEV_POLICY_ES | SEV_POLICY_NO_DBG); 202 172 test_sev(guest_sev_es_code, SEV_POLICY_ES); 173 + 174 + test_sev_es_shutdown(); 203 175 204 176 if (kvm_has_cap(KVM_CAP_XCRS) && 205 177 (xgetbv(0) & XFEATURE_MASK_X87_AVX) == XFEATURE_MASK_X87_AVX) {