|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
| 2 | +/* |
| 3 | + * IRQ routing offset tests. |
| 4 | + * |
| 5 | + * Copyright IBM Corp. 2026 |
| 6 | + * |
| 7 | + * Authors: |
| 8 | + * Janosch Frank <[email protected]> |
| 9 | + */ |
| 10 | +#include <stdio.h> |
| 11 | +#include <stdlib.h> |
| 12 | +#include <string.h> |
| 13 | +#include <sys/ioctl.h> |
| 14 | + |
| 15 | +#include "test_util.h" |
| 16 | +#include "kvm_util.h" |
| 17 | +#include "kselftest.h" |
| 18 | +#include "ucall_common.h" |
| 19 | + |
| 20 | +extern char guest_code[]; |
| 21 | +asm("guest_code:\n" |
| 22 | + "diag %r0,%r0,0\n" |
| 23 | + "j .\n"); |
| 24 | + |
| 25 | +static void test(void) |
| 26 | +{ |
| 27 | + struct kvm_irq_routing *routing; |
| 28 | + struct kvm_vcpu *vcpu; |
| 29 | + struct kvm_vm *vm; |
| 30 | + vm_paddr_t mem; |
| 31 | + int ret; |
| 32 | + |
| 33 | + struct kvm_irq_routing_entry ue = { |
| 34 | + .type = KVM_IRQ_ROUTING_S390_ADAPTER, |
| 35 | + .gsi = 1, |
| 36 | + }; |
| 37 | + |
| 38 | + vm = vm_create_with_one_vcpu(&vcpu, guest_code); |
| 39 | + mem = vm_phy_pages_alloc(vm, 2, 4096 * 42, 0); |
| 40 | + |
| 41 | + routing = kvm_gsi_routing_create(); |
| 42 | + routing->nr = 1; |
| 43 | + routing->entries[0] = ue; |
| 44 | + routing->entries[0].u.adapter.summary_addr = (uintptr_t)mem; |
| 45 | + routing->entries[0].u.adapter.ind_addr = (uintptr_t)mem; |
| 46 | + |
| 47 | + routing->entries[0].u.adapter.summary_offset = 4096 * 8; |
| 48 | + ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing); |
| 49 | + ksft_test_result(ret == -1 && errno == EINVAL, "summary offset outside of page\n"); |
| 50 | + |
| 51 | + routing->entries[0].u.adapter.summary_offset -= 4; |
| 52 | + ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing); |
| 53 | + ksft_test_result(ret == 0, "summary offset inside of page\n"); |
| 54 | + |
| 55 | + routing->entries[0].u.adapter.ind_offset = 4096 * 8; |
| 56 | + ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing); |
| 57 | + ksft_test_result(ret == -1 && errno == EINVAL, "ind offset outside of page\n"); |
| 58 | + |
| 59 | + routing->entries[0].u.adapter.ind_offset -= 4; |
| 60 | + ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing); |
| 61 | + ksft_test_result(ret == 0, "ind offset inside of page\n"); |
| 62 | + |
| 63 | + kvm_vm_free(vm); |
| 64 | +} |
| 65 | + |
| 66 | +int main(int argc, char *argv[]) |
| 67 | +{ |
| 68 | + TEST_REQUIRE(kvm_has_cap(KVM_CAP_IRQ_ROUTING)); |
| 69 | + |
| 70 | + ksft_print_header(); |
| 71 | + ksft_set_plan(4); |
| 72 | + test(); |
| 73 | + |
| 74 | + ksft_finished(); /* Print results and exit() accordingly */ |
| 75 | +} |
0 commit comments