]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: s390: selftests: Add IRQ routing address offset tests
authorJanosch Frank <frankja@linux.ibm.com>
Tue, 3 Mar 2026 13:46:35 +0000 (13:46 +0000)
committerChristian Borntraeger <borntraeger@linux.ibm.com>
Mon, 16 Mar 2026 15:56:39 +0000 (16:56 +0100)
This test tries to setup routes which have address + offset
combinations which cross a page.

Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
tools/testing/selftests/kvm/Makefile.kvm
tools/testing/selftests/kvm/s390/irq_routing.c [new file with mode: 0644]

index fdec90e854671fff0b6050a46b21fbd6dc5d1423..271cbb63af36d87f1cafd1c301d0426aafd67d42 100644 (file)
@@ -205,6 +205,7 @@ TEST_GEN_PROGS_s390 += s390/ucontrol_test
 TEST_GEN_PROGS_s390 += s390/user_operexec
 TEST_GEN_PROGS_s390 += s390/keyop
 TEST_GEN_PROGS_s390 += rseq_test
+TEST_GEN_PROGS_s390 += s390/irq_routing
 
 TEST_GEN_PROGS_riscv = $(TEST_GEN_PROGS_COMMON)
 TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
diff --git a/tools/testing/selftests/kvm/s390/irq_routing.c b/tools/testing/selftests/kvm/s390/irq_routing.c
new file mode 100644 (file)
index 0000000..7819a0a
--- /dev/null
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * IRQ routing offset tests.
+ *
+ * Copyright IBM Corp. 2026
+ *
+ * Authors:
+ *  Janosch Frank <frankja@linux.ibm.com>
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "kselftest.h"
+#include "ucall_common.h"
+
+extern char guest_code[];
+asm("guest_code:\n"
+    "diag %r0,%r0,0\n"
+    "j .\n");
+
+static void test(void)
+{
+       struct kvm_irq_routing *routing;
+       struct kvm_vcpu *vcpu;
+       struct kvm_vm *vm;
+       vm_paddr_t mem;
+       int ret;
+
+       struct kvm_irq_routing_entry ue = {
+               .type = KVM_IRQ_ROUTING_S390_ADAPTER,
+               .gsi = 1,
+       };
+
+       vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+       mem = vm_phy_pages_alloc(vm, 2, 4096 * 42, 0);
+
+       routing = kvm_gsi_routing_create();
+       routing->nr = 1;
+       routing->entries[0] = ue;
+       routing->entries[0].u.adapter.summary_addr = (uintptr_t)mem;
+       routing->entries[0].u.adapter.ind_addr = (uintptr_t)mem;
+
+       routing->entries[0].u.adapter.summary_offset = 4096 * 8;
+       ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing);
+       ksft_test_result(ret == -1 && errno == EINVAL, "summary offset outside of page\n");
+
+       routing->entries[0].u.adapter.summary_offset -= 4;
+       ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing);
+       ksft_test_result(ret == 0, "summary offset inside of page\n");
+
+       routing->entries[0].u.adapter.ind_offset = 4096 * 8;
+       ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing);
+       ksft_test_result(ret == -1 && errno == EINVAL, "ind offset outside of page\n");
+
+       routing->entries[0].u.adapter.ind_offset -= 4;
+       ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing);
+       ksft_test_result(ret == 0, "ind offset inside of page\n");
+
+       kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+       TEST_REQUIRE(kvm_has_cap(KVM_CAP_IRQ_ROUTING));
+
+       ksft_print_header();
+       ksft_set_plan(4);
+       test();
+
+       ksft_finished();        /* Print results and exit() accordingly */
+}