Message ID | 20240203000917.376631-11-seanjc@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: selftests: Add SEV smoke test | expand |
On Fri, Feb 02, 2024, Sean Christopherson wrote: > +int main(int argc, char *argv[]) > +{ > + TEST_REQUIRE(is_kvm_sev_supported()); This also needs TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); to handle the case where the platform supports SEV, i.e. /dev/sev exists, but KVM doesn't support SEV, e.g. if TDP is disabled, if SEV was explicitly disabled via module param, etc.
On Tue, Feb 06, 2024, Sean Christopherson wrote: > On Fri, Feb 02, 2024, Sean Christopherson wrote: > > +int main(int argc, char *argv[]) > > +{ > > + TEST_REQUIRE(is_kvm_sev_supported()); > > This also needs > > TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); > > to handle the case where the platform supports SEV, i.e. /dev/sev exists, but > KVM doesn't support SEV, e.g. if TDP is disabled, if SEV was explicitly disabled > via module param, etc. Thinking more about this, I think we should simply delete is_kvm_sev_supported(). (a) it obviously doesn't query _KVM_ support, and (b) if KVM says SEV is supported, then it darn well actually be supported.
On Thu, Feb 22, 2024, Sean Christopherson wrote: > On Tue, Feb 06, 2024, Sean Christopherson wrote: > > On Fri, Feb 02, 2024, Sean Christopherson wrote: > > > +int main(int argc, char *argv[]) > > > +{ > > > + TEST_REQUIRE(is_kvm_sev_supported()); > > > > This also needs > > > > TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); > > > > to handle the case where the platform supports SEV, i.e. /dev/sev exists, but > > KVM doesn't support SEV, e.g. if TDP is disabled, if SEV was explicitly disabled > > via module param, etc. > > Thinking more about this, I think we should simply delete is_kvm_sev_supported(). > (a) it obviously doesn't query _KVM_ support, and (b) if KVM says SEV is supported, > then it darn well actually be supported. Ugh, and selftests also need to handle the scenario where SEV is enabled, but all ASIDs are assigned to SEV-ES. We could try to create a dummy VM and check for an -EBUSY return, but that is ugly and could result in missing KVM bugs due to tests being skipped instead of failing. That's a future problem though, because I think we'll need new KVM functionality to surface that information.
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 169b6ee8f733..da20e6bb43ed 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -120,6 +120,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests +TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test TEST_GEN_PROGS_x86_64 += x86_64/amx_test TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test diff --git a/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c new file mode 100644 index 000000000000..c1534efab2be --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" +#include "svm_util.h" +#include "linux/psp-sev.h" +#include "sev.h" + +static void guest_sev_code(void) +{ + GUEST_ASSERT(this_cpu_has(X86_FEATURE_SEV)); + GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED); + + GUEST_DONE(); +} + +static void test_sev(void *guest_code, uint64_t policy) +{ + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + struct ucall uc; + + vm = vm_sev_create_with_one_vcpu(policy, guest_code, &vcpu); + + for (;;) { + vcpu_run(vcpu); + + switch (get_ucall(vcpu, &uc)) { + case UCALL_SYNC: + continue; + case UCALL_DONE: + return; + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + default: + TEST_FAIL("Unexpected exit: %s", + exit_reason_str(vcpu->run->exit_reason)); + } + } + + kvm_vm_free(vm); +} + +int main(int argc, char *argv[]) +{ + TEST_REQUIRE(is_kvm_sev_supported()); + + test_sev(guest_sev_code, SEV_POLICY_NO_DBG); + test_sev(guest_sev_code, 0); + + return 0; +}