lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250923050942.206116-36-Neeraj.Upadhyay@amd.com>
Date: Tue, 23 Sep 2025 10:39:42 +0530
From: Neeraj Upadhyay <Neeraj.Upadhyay@....com>
To: <kvm@...r.kernel.org>, <seanjc@...gle.com>, <pbonzini@...hat.com>
CC: <linux-kernel@...r.kernel.org>, <Thomas.Lendacky@....com>,
	<nikunj@....com>, <Santosh.Shukla@....com>, <Vasant.Hegde@....com>,
	<Suravee.Suthikulpanit@....com>, <bp@...en8.de>, <David.Kaplan@....com>,
	<huibo.wang@....com>, <naveen.rao@....com>, <pgonda@...gle.com>,
	<linux-kselftest@...r.kernel.org>, <shuah@...nel.org>, <tiala@...rosoft.com>
Subject: [RFC PATCH v2 35/35] KVM: selftests: Add MSI injection test for SAVIC

Extend the Secure AVIC (SAVIC) selftest to validate the injection of
Message-Signaled Interrupts (MSIs) from the host.

In SAVIC mode, the delivery of external interrupts, including MSIs,
requires explicit cooperation from the guest. For an interrupt to be
successfully injected by the hardware, the guest must first grant
permission by setting the corresponding vector bit in the 'ALLOWED IRR'
region of its private APIC backing page. If the vector is not explicitly
allowed, the hardware will drop the interrupt.

Add a new test case to Secure AVIC selftest that verifies this permission
model for MSIs. Verify that:

1.  If the host injects an MSI while the guest has not yet allowed the
    vector, the interrupt is correctly dropped and not received.
2.  The guest then updates the ALLOWED_IRR to permit the MSI vector. When
    the host injects the same MSI again, the interrupt is successfully
    delivered and handled.

This two-stage approach provides robust validation of the SAVIC MSI
delivery mechanism, ensuring both the blocking and permissive paths
work as expected.

Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@....com>
---
 tools/testing/selftests/kvm/x86/savic_test.c | 49 ++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/tools/testing/selftests/kvm/x86/savic_test.c b/tools/testing/selftests/kvm/x86/savic_test.c
index 3efefc1e69f5..1d9861949a28 100644
--- a/tools/testing/selftests/kvm/x86/savic_test.c
+++ b/tools/testing/selftests/kvm/x86/savic_test.c
@@ -22,6 +22,7 @@
 #define IOAPIC_NUM_LEVEL_VECTORS 2
 #define RTC_GSI	8
 #define RTC_GSI_IRQ 0x85
+#define MSI_VECTOR 0x40
 #define FIXED_IPI_VEC     0x31
 #define FIXED_LOGICAL_IPI_VEC     0x32
 #define BROADCAST_ALL_IPI_VEC     0x33
@@ -40,6 +41,7 @@ enum savic_test_state {
 	SAVIC_TEST_STATE(SAVIC_IDLE_HALT),
 	SAVIC_TEST_STATE(SAVIC_IOAPIC),
 	SAVIC_TEST_STATE(SAVIC_IOAPIC2),
+	SAVIC_TEST_STATE(SAVIC_MSI),
 	SAVIC_TEST_STATE(SAVIC_IPI),
 	SAVIC_TEST_STATE(SAVIC_NMI),
 	SAVIC_TEST_STATE(SAVIC_NMI2),
@@ -57,6 +59,7 @@ struct test_data_page {
 	uint64_t ioapic_lirq1_count;
 	uint64_t ioapic_lirq2_count;
 	uint64_t ioapic_rtc_gsi_irq_count;
+	uint64_t msi_irq_count;
 	uint64_t fixed_phys_ipi_wake_count;
 	uint64_t fixed_phys_ipi_hlt_count;
 	uint64_t fixed_logical_ipi_hlt_count;
@@ -807,6 +810,34 @@ static void guest_nmi_handler(struct ex_regs *regs)
 		sev_es_nmi_complete();
 }
 
+static void savic_msi_not_allowed(int id)
+{
+	struct test_data_page *data = get_test_data();
+
+	savic_allow_vector(MSI_VECTOR);
+
+	__GUEST_ASSERT(READ_ONCE(data->msi_irq_count) == 0,
+			"Invalid MSI IRQ count: %ld, should be 0",
+			READ_ONCE(data->msi_irq_count));
+}
+
+static void savic_msi_allowed(int id)
+{
+	struct test_data_page *data = get_test_data();
+
+	__GUEST_ASSERT(READ_ONCE(data->msi_irq_count) == 1,
+			"Invalid MSI IRQ count: %ld",
+			READ_ONCE(data->msi_irq_count));
+}
+
+static void msi_intr_handler(struct ex_regs *regs)
+{
+	struct test_data_page *data = get_test_data();
+
+	 WRITE_ONCE(data->msi_irq_count, data->msi_irq_count + 1);
+	 x2apic_write_reg(APIC_EOI, 0x00);
+}
+
 static void ipi_guest_code(int id)
 {
 	struct test_data_page *data;
@@ -901,6 +932,9 @@ static void guest_code(int id)
 	SAVIC_GUEST_SYNC(SAVIC_IOAPIC, savic_ioapic);
 	SAVIC_GUEST_SYNC(SAVIC_IOAPIC2, savic_ioapic2);
 
+	SAVIC_GUEST_SYNC(SAVIC_MSI, savic_msi_not_allowed);
+	SAVIC_GUEST_SYNC(SAVIC_MSI, savic_msi_allowed);
+
 	SAVIC_GUEST_SYNC(SAVIC_IPI, savic_ipi);
 
 	/* Disable host NMI injection in control MSR. */
@@ -953,6 +987,17 @@ static void host_send_ioapic_irq(struct kvm_vm *vm, int id)
 	kvm_irq_line_status(vm, RTC_GSI, 0);
 }
 
+static void host_send_msi(struct kvm_vm *vm)
+{
+	struct kvm_msi msi = {
+		.address_lo = 0,
+		.address_hi = 0,
+		.data = MSI_VECTOR,
+	};
+
+	__vm_ioctl(vm, KVM_SIGNAL_MSI, &msi);
+}
+
 static void host_send_nmi(int id)
 {
 	vcpu_nmi(vcpus[id]);
@@ -968,6 +1013,9 @@ static void host_test_savic(struct kvm_vm *vm, int id, enum savic_test_state tes
 	case SAVIC_IOAPIC2_START:
 		host_send_ioapic_irq(vm, id);
 		break;
+	case SAVIC_MSI_START:
+		host_send_msi(vm);
+		break;
 	case SAVIC_NMI_START:
 	case SAVIC_NMI2_START:
 	case SAVIC_NMI3_START:
@@ -1021,6 +1069,7 @@ static void install_exception_handlers(struct kvm_vm *vm)
 	vm_install_exception_handler(vm, BROADCAST_NOSELF_IPI_VEC,
 			guest_broadcast_noself_ipi_handler);
 	vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
+	vm_install_exception_handler(vm, MSI_VECTOR, msi_intr_handler);
 }
 
 int main(int argc, char *argv[])
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ