From: ma.mandourr@gmail.com
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Mahmoud Abumandour <ma.mandourr@gmail.com>
Subject: [PATCH 2/2] KVM: selftests: Add test for nested VM-Exits while vectoring soft INTs
Date: Tue, 20 Oct 2026 21:26:03 -0700 [thread overview]
Message-ID: <20261021042603.608292-3-ma.mandourr@gmail.com> (raw)
In-Reply-To: <20261021042603.608292-1-ma.mandourr@gmail.com>
From: Mahmoud Abumandour <ma.mandourr@gmail.com>
Verify that a VM-Exit from L2 that occurs while vectoring INT3 or INTn
reports the instruction length in the VM-Exit instruction length field and
leaves L1's VM-Entry instruction length untouched.
Assisted-by: LLM
Signed-off-by: Mahmoud Abumandour <ma.mandourr@gmail.com>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../kvm/x86/vmx_soft_int_vectoring_test.c | 105 ++++++++++++++++++
2 files changed, 106 insertions(+)
create mode 100644 tools/testing/selftests/kvm/x86/vmx_soft_int_vectoring_test.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 888a7530a280..d5f8749413f2 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -140,6 +140,7 @@ TEST_GEN_PROGS_x86 += x86/vmx_exception_with_invalid_guest_state
TEST_GEN_PROGS_x86 += x86/vmx_msrs_test
TEST_GEN_PROGS_x86 += x86/vmx_invalid_nested_guest_state
TEST_GEN_PROGS_x86 += x86/vmx_nested_la57_state_test
+TEST_GEN_PROGS_x86 += x86/vmx_soft_int_vectoring_test
TEST_GEN_PROGS_x86 += x86/apic_bus_clock_test
TEST_GEN_PROGS_x86 += x86/xapic_ipi_test
TEST_GEN_PROGS_x86 += x86/xapic_state_test
diff --git a/tools/testing/selftests/kvm/x86/vmx_soft_int_vectoring_test.c b/tools/testing/selftests/kvm/x86/vmx_soft_int_vectoring_test.c
new file mode 100644
index 000000000000..e74510c49938
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86/vmx_soft_int_vectoring_test.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Verify that a nested VM-Exit that occurs while L2 is vectoring a software
+ * exception (INT3) or a software interrupt (INTn) reports the length of the
+ * instruction in the VM-Exit instruction length field, and doesn't modify the
+ * VM-Entry instruction length field, a VM-Entry control that only L1 writes.
+ */
+#include "kvm_util.h"
+#include "processor.h"
+#include "vmx.h"
+#include "kselftest.h"
+
+#define INTR_INFO_VALID_MASK BIT(31)
+#define INTR_TYPE_SOFT_INTR (4 << 8)
+#define INTR_TYPE_SOFT_EXCEPTION (6 << 8)
+
+#define SOFT_INT_VECTOR 0x40
+
+/*
+ * Arbitrary, but a legal instruction length that differs from the lengths of
+ * INT3 and INTn, i.e. a value no VM-Exit in this test can legitimately produce.
+ */
+#define ENTRY_INSN_LEN 7
+
+static void l2_guest_code(void)
+{
+ asm volatile("int3");
+ asm volatile("int $" __stringify(SOFT_INT_VECTOR));
+ vmcall();
+}
+
+static void l1_assert_vectoring_exit(const char *insn, u32 vectoring_info,
+ u32 insn_len)
+{
+ u64 entry_insn_len;
+
+ GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_EXCEPTION_NMI);
+ GUEST_ASSERT_EQ(vmread(VM_EXIT_INTR_INFO) & 0xff, GP_VECTOR);
+ GUEST_ASSERT_EQ(vmread(IDT_VECTORING_INFO_FIELD),
+ INTR_INFO_VALID_MASK | vectoring_info);
+ GUEST_ASSERT_EQ(vmread(VM_EXIT_INSTRUCTION_LEN), insn_len);
+
+ entry_insn_len = vmread(VM_ENTRY_INSTRUCTION_LEN);
+ __GUEST_ASSERT(entry_insn_len == ENTRY_INSN_LEN,
+ "VM-Exit while vectoring %s changed the VM-Entry instruction length from %u to %lu",
+ insn, ENTRY_INSN_LEN, entry_insn_len);
+
+ /* RIP points at the INT3/INTn, skip it. */
+ vmwrite(GUEST_RIP, vmread(GUEST_RIP) + insn_len);
+}
+
+static void l1_guest_code(struct vmx_pages *vmx_pages)
+{
+ prepare_for_vmx_operation(vmx_pages);
+ load_vmcs(vmx_pages);
+ prepare_vmcs(vmx_pages, l2_guest_code);
+
+ /*
+ * Put every IDT entry beyond the limit so that vectoring any event in
+ * L2 generates #GP, and intercept #GP so that the VM-Exit occurs while
+ * the original event is being vectored.
+ */
+ vmwrite(GUEST_IDTR_LIMIT, 0);
+ vmwrite(EXCEPTION_BITMAP, BIT(GP_VECTOR));
+ vmwrite(VM_ENTRY_INSTRUCTION_LEN, ENTRY_INSN_LEN);
+
+ vmlaunch();
+ l1_assert_vectoring_exit("INT3", INTR_TYPE_SOFT_EXCEPTION | BP_VECTOR, 1);
+
+ vmresume();
+ l1_assert_vectoring_exit("INTn", INTR_TYPE_SOFT_INTR | SOFT_INT_VECTOR, 2);
+
+ vmresume();
+ GUEST_ASSERT_EQ(vmread(VM_EXIT_REASON), EXIT_REASON_VMCALL);
+ GUEST_DONE();
+}
+
+int main(int argc, char *argv[])
+{
+ gva_t vmx_pages_gva;
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+ struct ucall uc;
+
+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));
+
+ vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
+ vcpu_alloc_vmx(vm, &vmx_pages_gva);
+ vcpu_args_set(vcpu, 1, vmx_pages_gva);
+
+ vcpu_run(vcpu);
+ TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
+
+ switch (get_ucall(vcpu, &uc)) {
+ case UCALL_ABORT:
+ REPORT_GUEST_ASSERT(uc);
+ case UCALL_DONE:
+ break;
+ default:
+ TEST_FAIL("Unexpected ucall %lu", uc.cmd);
+ }
+
+ kvm_vm_free(vm);
+ return 0;
+}
--
2.43.0
next prev parent reply other threads:[~2026-10-21 4:26 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 4:26 [PATCH 0/2] KVM: nVMX: Don't clobber VM-Entry instruction length on soft INTn exits ma.mandourr
2026-10-21 4:26 ` [PATCH 1/2] KVM: nVMX: Don't clobber VM-Entry instruction length when saving soft INTn ma.mandourr
2026-10-21 4:42 ` sashiko-bot
2026-10-21 4:26 ` ma.mandourr [this message]
2026-10-21 4:45 ` [PATCH 2/2] KVM: selftests: Add test for nested VM-Exits while vectoring soft INTs sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261021042603.608292-3-ma.mandourr@gmail.com \
--to=ma.mandourr@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.