From: Hao Zhang <hao_zhang_kdev@163.com>
To: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>, kvm@vger.kernel.org
Subject: [PATCH 2/2] KVM: selftests: Verify IOAPIC doesn't set remote_irr on failed delivery
Date: Thu, 6 Aug 2026 21:46:54 +0800 [thread overview]
Message-ID: <anSQTobr7UThcimc@192.168.1.215> (raw)
In-Reply-To: <anSOdijwS6LBbfYJ@192.168.1.215>
From: Hao Zhang <zhanghao1@kylinos.cn>
Add a regression test for level-triggered I/O APIC interrupt delivery
when no local APIC can accept the interrupt.
remote_irr tracks that a level-triggered interrupt has been accepted by a
local APIC and that the I/O APIC must wait for the corresponding EOI before
delivering the interrupt again. If no local APIC accepts the interrupt,
remote_irr must remain clear, as no EOI will ever be generated.
Configure an I/O APIC redirection entry and inject an I/O APIC-only GSI
before creating any vCPUs. Verify that KVM_IRQ_LINE_STATUS reports failed
delivery and that KVM_GET_IRQCHIP reports remote_irr clear.
This covers the case where failed delivery returns a negative value and
must not be treated as a successful delivery for remote_irr tracking.
Signed-off-by: Hao Zhang <zhanghao1@kylinos.cn>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../testing/selftests/kvm/x86/ioapic_state_test.c | 70 ++++++++++++++++++++++
2 files changed, 71 insertions(+)
create mode 100644 tools/testing/selftests/kvm/x86/ioapic_state_test.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 6fc34e9bf8e1..89e3f82e75b0 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -86,6 +86,7 @@ TEST_GEN_PROGS_x86 += x86/hyperv_features
TEST_GEN_PROGS_x86 += x86/hyperv_ipi
TEST_GEN_PROGS_x86 += x86/hyperv_svm_test
TEST_GEN_PROGS_x86 += x86/hyperv_tlb_flush
+TEST_GEN_PROGS_x86 += x86/ioapic_state_test
TEST_GEN_PROGS_x86 += x86/kvm_clock_test
TEST_GEN_PROGS_x86 += x86/kvm_pv_test
TEST_GEN_PROGS_x86 += x86/kvm_buslock_test
diff --git a/tools/testing/selftests/kvm/x86/ioapic_state_test.c b/tools/testing/selftests/kvm/x86/ioapic_state_test.c
new file mode 100644
index 000000000000..3e1badcc391c
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86/ioapic_state_test.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Regression tests for in-kernel I/O APIC state.
+ */
+
+#include "kvm_util.h"
+#include "test_util.h"
+
+#define TEST_IOAPIC_PIN 16
+#define TEST_VECTOR 0x50
+#define NO_SUCH_APIC_ID 0xfe
+
+static void get_ioapic(struct kvm_vm *vm, struct kvm_irqchip *irqchip)
+{
+ int r;
+
+ irqchip->chip_id = KVM_IRQCHIP_IOAPIC;
+ r = __vm_ioctl(vm, KVM_GET_IRQCHIP, irqchip);
+ if (r && errno == ENXIO)
+ __TEST_REQUIRE(0, "In-kernel I/O APIC not available");
+
+ TEST_ASSERT(!r, KVM_IOCTL_ERROR(KVM_GET_IRQCHIP, r));
+}
+
+static void set_ioapic(struct kvm_vm *vm, struct kvm_irqchip *irqchip)
+{
+ irqchip->chip_id = KVM_IRQCHIP_IOAPIC;
+ vm_ioctl(vm, KVM_SET_IRQCHIP, irqchip);
+}
+
+static void test_no_remote_irr_for_undelivered_interrupt(void)
+{
+ struct kvm_irq_level irq = {
+ .irq = TEST_IOAPIC_PIN,
+ .level = 1,
+ };
+ struct kvm_irqchip irqchip;
+ struct kvm_vm *vm;
+
+ vm = vm_create_barebones();
+ vm_create_irqchip(vm);
+
+ get_ioapic(vm, &irqchip);
+
+ irqchip.chip.ioapic.redirtbl[TEST_IOAPIC_PIN].fields.vector = TEST_VECTOR;
+ irqchip.chip.ioapic.redirtbl[TEST_IOAPIC_PIN].fields.dest_id = NO_SUCH_APIC_ID;
+ irqchip.chip.ioapic.redirtbl[TEST_IOAPIC_PIN].fields.dest_mode = 0;
+ irqchip.chip.ioapic.redirtbl[TEST_IOAPIC_PIN].fields.trig_mode = 1;
+ irqchip.chip.ioapic.redirtbl[TEST_IOAPIC_PIN].fields.mask = 0;
+ irqchip.chip.ioapic.redirtbl[TEST_IOAPIC_PIN].fields.remote_irr = 0;
+
+ set_ioapic(vm, &irqchip);
+
+ vm_ioctl(vm, KVM_IRQ_LINE_STATUS, &irq);
+ TEST_ASSERT(irq.status == -1,
+ "Expected failed interrupt delivery, got %d", irq.status);
+
+ get_ioapic(vm, &irqchip);
+ TEST_ASSERT(!irqchip.chip.ioapic.redirtbl[TEST_IOAPIC_PIN].fields.remote_irr,
+ "KVM set remote_irr for a level-triggered interrupt that wasn't delivered");
+
+ kvm_vm_free(vm);
+}
+
+int main(void)
+{
+ test_no_remote_irr_for_undelivered_interrupt();
+
+ return 0;
+}
--
2.15.0
next prev parent reply other threads:[~2026-08-06 13:47 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 13:39 [PATCH 1/2] KVM: x86: ioapic: Set remote_irr only after successful delivery Hao Zhang
2026-08-06 13:46 ` Hao Zhang [this message]
2026-08-07 7:41 ` Huang, Kai
2026-08-10 1:39 ` hao_zhang_kdev
2026-08-10 8:44 ` Huang, Kai
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=anSQTobr7UThcimc@192.168.1.215 \
--to=hao_zhang_kdev@163.com \
--cc=kvm@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.