mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/3] KVM: nVMX: Don't clobber VM-Entry instruction length on soft INTn exits
@ 2026-10-23  0:37 ma.mandourr
  2026-10-23  0:37 ` [PATCH v2 1/3] KVM: nVMX: Fill VM-Exit instruction length before saving pending event ma.mandourr
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: ma.mandourr @ 2026-10-23  0:37 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, ma.mandourr

From: Mahmoud Abumandour <ma.mandourr@gmail.com>

KVM writes the length of a soft INTn that L2 was vectoring at the time of a
nested VM-Exit into vmcs12's VM-Entrty instruction length instead of the VM-Exit
instruction length.

Patch 1 did not exist in v1, but Sashiko pointed out that prepare_vmcs12()
overwrites the VM-exit instruction length that vmcs12_save_pending_event() saves
for soft events.

The selftest patch was written with the help of an LLM (Claude Opus 5.5).

v2:
 - New Patch 1
 - Same Patch 2 from v1 (with commit message changes)
 - Patch 3 now extends nested_exceptions_test instead of adding a new test
   (suggested by Sashiko).

v1: https://lore.kernel.org/all/20261021042603.608292-1-ma.mandourr@gmail.com

Mahmoud Abumandour (3):
  KVM: nVMX: Fill VM-Exit instruction length before saving pending event
  KVM: nVMX: Don't clobber VM-Entry instruction length when saving soft
    INTn
  KVM: selftests: Verify nested VM-Exits while vectoring INT3 and INTn

 arch/x86/kvm/vmx/nested.c                     |  6 ++-
 .../kvm/x86/nested_exceptions_test.c          | 39 +++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/3] KVM: nVMX: Fill VM-Exit instruction length before saving pending event
  2026-10-23  0:37 [PATCH v2 0/3] KVM: nVMX: Don't clobber VM-Entry instruction length on soft INTn exits ma.mandourr
@ 2026-10-23  0:37 ` ma.mandourr
  2026-10-23  0:37 ` [PATCH v2 2/3] KVM: nVMX: Don't clobber VM-Entry instruction length when saving soft INTn ma.mandourr
  2026-10-23  0:37 ` [PATCH v2 3/3] KVM: selftests: Verify nested VM-Exits while vectoring INT3 and INTn ma.mandourr
  2 siblings, 0 replies; 4+ messages in thread
From: ma.mandourr @ 2026-10-23  0:37 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, ma.mandourr

From: Mahmoud Abumandour <ma.mandourr@gmail.com>

Fill vmcs12's VM-Exit instruction length before calling
vmcs12_save_pending_event(), so that the length it saves for a software
exception isn't overwritten.  Commit c3634d25fbee ("KVM: nVMX: Leave most
VM-Exit info fields unmodified on failed VM-Entry") moved the assignment
after the call.

L1 sees no difference since both lengths are read from vmcs02's VM-Exit
instruction length.

Link: https://lore.kernel.org/all/sashiko-outbox-179791@kernel.org
Signed-off-by: Mahmoud Abumandour <ma.mandourr@gmail.com>
---
 arch/x86/kvm/vmx/nested.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 9b0bfa2f854c..6f7c00083beb 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -4764,6 +4764,9 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
 		 * instead of reading the real value. */
 		vmcs12->vm_entry_intr_info_field &= ~INTR_INFO_VALID_MASK;
 
+		/* vmcs12_save_pending_event() may override this. */
+		vmcs12->vm_exit_instruction_len = exit_insn_len;
+
 		/*
 		 * Transfer the event that L0 or L1 may wanted to inject into
 		 * L2 to IDT_VECTORING_INFO_FIELD.
@@ -4772,7 +4775,6 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
 					  vm_exit_reason, exit_intr_info);
 
 		vmcs12->vm_exit_intr_info = exit_intr_info;
-		vmcs12->vm_exit_instruction_len = exit_insn_len;
 		vmcs12->vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
 
 		/*
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 2/3] KVM: nVMX: Don't clobber VM-Entry instruction length when saving soft INTn
  2026-10-23  0:37 [PATCH v2 0/3] KVM: nVMX: Don't clobber VM-Entry instruction length on soft INTn exits ma.mandourr
  2026-10-23  0:37 ` [PATCH v2 1/3] KVM: nVMX: Fill VM-Exit instruction length before saving pending event ma.mandourr
@ 2026-10-23  0:37 ` ma.mandourr
  2026-10-23  0:37 ` [PATCH v2 3/3] KVM: selftests: Verify nested VM-Exits while vectoring INT3 and INTn ma.mandourr
  2 siblings, 0 replies; 4+ messages in thread
From: ma.mandourr @ 2026-10-23  0:37 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, ma.mandourr

From: Mahmoud Abumandour <ma.mandourr@gmail.com>

When a nested VM-Exit occurs while L2 is vectoring a software interrupt,
save the INTn's length in vmcs12's VM-Exit instruction length, as is
done for software exceptions, instead of VM-Entry instruction length.

Fixes: 5f3d5799974b ("KVM: nVMX: Rework event injection and recovery")
Signed-off-by: Mahmoud Abumandour <ma.mandourr@gmail.com>
---
 arch/x86/kvm/vmx/nested.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 6f7c00083beb..4286b0503046 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -4016,7 +4016,7 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu,
 
 		if (vcpu->arch.interrupt.soft) {
 			idt_vectoring |= INTR_TYPE_SOFT_INTR;
-			vmcs12->vm_entry_instruction_len =
+			vmcs12->vm_exit_instruction_len =
 				vcpu->arch.event_exit_inst_len;
 		} else
 			idt_vectoring |= INTR_TYPE_EXT_INTR;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 3/3] KVM: selftests: Verify nested VM-Exits while vectoring INT3 and INTn
  2026-10-23  0:37 [PATCH v2 0/3] KVM: nVMX: Don't clobber VM-Entry instruction length on soft INTn exits ma.mandourr
  2026-10-23  0:37 ` [PATCH v2 1/3] KVM: nVMX: Fill VM-Exit instruction length before saving pending event ma.mandourr
  2026-10-23  0:37 ` [PATCH v2 2/3] KVM: nVMX: Don't clobber VM-Entry instruction length when saving soft INTn ma.mandourr
@ 2026-10-23  0:37 ` ma.mandourr
  2 siblings, 0 replies; 4+ messages in thread
From: ma.mandourr @ 2026-10-23  0:37 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, ma.mandourr

From: Mahmoud Abumandour <ma.mandourr@gmail.com>

Verify that a VM-Exit while L2 is vectoring INT3 or INTn through the
empty IDT reports the event and its instruction length, and leaves the
VM-Entry instruction length alone. Only VMX is tested, as both lengths
are VMX fields.

Assisted-by: LLM
Signed-off-by: Mahmoud Abumandour <ma.mandourr@gmail.com>
---
 .../kvm/x86/nested_exceptions_test.c          | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
index f47432526ea1..9311af590566 100644
--- a/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
+++ b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
@@ -40,12 +40,25 @@
 #define GP_ERROR_CODE_INTEL ((SS_VECTOR * 8) | ERROR_CODE_IDT_FLAG | ERROR_CODE_EXT_FLAG)
 #define GP_ERROR_CODE_ZHAOXIN ((SS_VECTOR * 8) | ERROR_CODE_IDT_FLAG)
 
+/* No "External event" flag, as INT3 and INTn are software events. */
+#define GP_ERROR_CODE_SOFT_INT(vector) (((vector) * 8) | ERROR_CODE_IDT_FLAG)
+
 /*
  * Intel and AMD both shove '0' into the error code on #DF, regardless of what
  * led to the double fault.
  */
 #define DF_ERROR_CODE 0
 
+/* Arbitrary, any vector #GPs with the empty IDT. */
+#define INTN_VECTOR		0x40
+
+#define INTR_INFO_VALID_MASK		BIT(31)
+#define INTR_TYPE_SOFT_INTR		(4 << 8)
+#define INTR_TYPE_SOFT_EXCEPTION	(6 << 8)
+
+/* Arbitrary, but not the length of INT3 or INTn. */
+#define VM_ENTRY_INSN_LEN	7
+
 #define INTERCEPT_SS		(BIT_ULL(SS_VECTOR))
 #define INTERCEPT_SS_DF		(INTERCEPT_SS | BIT_ULL(DF_VECTOR))
 #define INTERCEPT_SS_GP_DF	(INTERCEPT_SS_DF | BIT_ULL(GP_VECTOR))
@@ -70,6 +83,16 @@ static void l2_ss_injected_tf_test(void)
 	GUEST_SYNC(FAKE_TRIPLE_FAULT_VECTOR);
 }
 
+static void l2_int3_test(void)
+{
+	asm volatile("int3");
+}
+
+static void l2_intn_test(void)
+{
+	asm volatile("int $" __stringify(INTN_VECTOR));
+}
+
 static void svm_run_l2(struct svm_test_data *svm, void *l2_code, int vector,
 		       u32 error_code)
 {
@@ -127,6 +150,18 @@ static void vmx_run_l2(void *l2_code, int vector, u32 error_code)
 	GUEST_ASSERT(!vmread(GUEST_INTERRUPTIBILITY_INFO));
 }
 
+static void vmx_run_l2_soft_int(void *l2_code, u32 type, int vector,
+				u32 insn_len)
+{
+	vmwrite(VM_ENTRY_INSTRUCTION_LEN, VM_ENTRY_INSN_LEN);
+	vmx_run_l2(l2_code, GP_VECTOR, GP_ERROR_CODE_SOFT_INT(vector));
+
+	GUEST_ASSERT_EQ(vmread(IDT_VECTORING_INFO_FIELD),
+			INTR_INFO_VALID_MASK | type | vector);
+	GUEST_ASSERT_EQ(vmread(VM_EXIT_INSTRUCTION_LEN), insn_len);
+	GUEST_ASSERT_EQ(vmread(VM_ENTRY_INSTRUCTION_LEN), VM_ENTRY_INSN_LEN);
+}
+
 static void l1_vmx_code(struct vmx_pages *vmx)
 {
 	prepare_for_vmx_operation(vmx);
@@ -146,6 +181,10 @@ static void l1_vmx_code(struct vmx_pages *vmx)
 	vmx_run_l2(l2_ss_injected_gp_test, GP_VECTOR,
 		   host_cpu_is_zhaoxin ? GP_ERROR_CODE_ZHAOXIN : GP_ERROR_CODE_INTEL);
 
+	/* INT3 and INTn also #GP, due to the empty IDT. */
+	vmx_run_l2_soft_int(l2_int3_test, INTR_TYPE_SOFT_EXCEPTION, BP_VECTOR, 1);
+	vmx_run_l2_soft_int(l2_intn_test, INTR_TYPE_SOFT_INTR, INTN_VECTOR, 2);
+
 	vmwrite(EXCEPTION_BITMAP, INTERCEPT_SS_DF);
 	vmx_run_l2(l2_ss_injected_df_test, DF_VECTOR, DF_ERROR_CODE);
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-23  0:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-23  0:37 [PATCH v2 0/3] KVM: nVMX: Don't clobber VM-Entry instruction length on soft INTn exits ma.mandourr
2026-10-23  0:37 ` [PATCH v2 1/3] KVM: nVMX: Fill VM-Exit instruction length before saving pending event ma.mandourr
2026-10-23  0:37 ` [PATCH v2 2/3] KVM: nVMX: Don't clobber VM-Entry instruction length when saving soft INTn ma.mandourr
2026-10-23  0:37 ` [PATCH v2 3/3] KVM: selftests: Verify nested VM-Exits while vectoring INT3 and INTn ma.mandourr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®