On Thu, 2022-11-03 at 16:13 +0200, Maxim Levitsky wrote: > Add test that tests that on SVM if L1 doesn't intercept SHUTDOWN, > then L2 crashes L1 and doesn't crash L2 I mean doesn't crash L0, sorry for typo. Best regards, Maxim Levitsky > > Signed-off-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx> > --- > tools/testing/selftests/kvm/.gitignore | 1 + > tools/testing/selftests/kvm/Makefile | 1 + > .../kvm/x86_64/svm_nested_shutdown_test.c | 67 +++++++++++++++++++ > 3 files changed, 69 insertions(+) > create mode 100644 tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c > > diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore > index 2f0d705db9dba5..05d980fb083d17 100644 > --- a/tools/testing/selftests/kvm/.gitignore > +++ b/tools/testing/selftests/kvm/.gitignore > @@ -41,6 +41,7 @@ > /x86_64/svm_vmcall_test > /x86_64/svm_int_ctl_test > /x86_64/svm_nested_soft_inject_test > +/x86_64/svm_nested_shutdown_test > /x86_64/sync_regs_test > /x86_64/tsc_msrs_test > /x86_64/tsc_scaling_sync > diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile > index 0172eb6cb6eee2..4a2caef2c9396f 100644 > --- a/tools/testing/selftests/kvm/Makefile > +++ b/tools/testing/selftests/kvm/Makefile > @@ -101,6 +101,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/state_test > TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test > TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test > TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test > +TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test > TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test > TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync > TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test > diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c b/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c > new file mode 100644 > index 00000000000000..e73fcdef47bbe9 > --- /dev/null > +++ b/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c > @@ -0,0 +1,67 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * svm_nested_shutdown_test > + * > + * Copyright (C) 2022, Red Hat, Inc. > + * > + * Nested SVM testing: test that unintercepted shutdown in L2 doesn't crash the host > + */ > + > +#include "test_util.h" > +#include "kvm_util.h" > +#include "processor.h" > +#include "svm_util.h" > + > +static void l2_guest_code(struct svm_test_data *svm) > +{ > + __asm__ __volatile__("ud2"); > +} > + > +static void l1_guest_code(struct svm_test_data *svm, struct idt_entry *idt) > +{ > + #define L2_GUEST_STACK_SIZE 64 > + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; > + struct vmcb *vmcb = svm->vmcb; > + > + generic_svm_setup(svm, l2_guest_code, > + &l2_guest_stack[L2_GUEST_STACK_SIZE]); > + > + vmcb->control.intercept &= ~(BIT(INTERCEPT_SHUTDOWN)); > + > + idt[6].p = 0; // #UD is intercepted but its injection will cause #NP > + idt[11].p = 0; // #NP is not intercepted and will cause another > + // #NP that will be converted to #DF > + idt[8].p = 0; // #DF will cause #NP which will cause SHUTDOWN > + > + run_guest(vmcb, svm->vmcb_gpa); > + > + /* should not reach here */ > + GUEST_ASSERT(0); > +} > + > +int main(int argc, char *argv[]) > +{ > + struct kvm_vcpu *vcpu; > + struct kvm_run *run; > + vm_vaddr_t svm_gva; > + struct kvm_vm *vm; > + > + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM)); > + > + vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code); > + vm_init_descriptor_tables(vm); > + vcpu_init_descriptor_tables(vcpu); > + > + vcpu_alloc_svm(vm, &svm_gva); > + > + vcpu_args_set(vcpu, 2, svm_gva, vm->idt); > + run = vcpu->run; > + > + vcpu_run(vcpu); > + TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN, > + "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n", > + run->exit_reason, > + exit_reason_str(run->exit_reason)); > + > + kvm_vm_free(vm); > +}