From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D25ED2248A0 for ; Sat, 30 May 2026 00:23:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780100596; cv=none; b=YM3SolhSqjwETe2b+FZrh88zk7kFl84heEgAxF42VewH10pk1LRxuRbU+/iTvunNMJUiJ2tmmb4KtPZYdMa3TnUler+Cg/8yyfkeevZdi1OY1Vbko7hHdbu5ah7CKBb1OBWWam6uIllvaGqfaKSzuGlwSDk11XGvthRNubbixlg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780100596; c=relaxed/simple; bh=aF6O9VsSjQ97pF3SrAsvLPtLXN6re5Q7TRYgYqYPOZQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=oWOkV/SkwsOd9a8ctpmgKawcHgkdLk9iW/Bs6f6qudv6xlkcc2tcJj99TNgMAXkao+mkCrWaj/R4xbfYZGryuyBu9EWsx/Nm6yJay/0+E/Oneo1cLfkYNP6Jbl02QBMvNuMWycjAl3UYDpSG5pFvdd/AQE7qVwP2MYu1N1tUEsU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jrhilke.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=EL3k2J+l; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jrhilke.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="EL3k2J+l" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2bf08c2a24bso26911025ad.2 for ; Fri, 29 May 2026 17:23:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780100594; x=1780705394; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=1p04x6ZghZmLiQW4r6y7TuUkEl7HeypX+13BZ14qNiE=; b=EL3k2J+lHvpsnI9YEkzX3rvrUYwExE4gsgH6CGJAuw0BQJTHlB98fMpIdSwzsFEZxN MRoqpDbU3S2gIp9yVERKBQHhBYM4L0YbviAkTssk9/ACFP1capT8fA9Du87zUDQ7Jh4n fkmTW/p6pp5rY+V6D4B1j9E9/dLWkEln7oU2vkIGrAq0Lsk46iSeX018ejridubYNCH3 EsxCJ2kVGmogsWtEqvS1FEQrq+Kmw5yblRoTJhPPbXGq6zo4NzKY9u9aHJMb8IFCV9WG KA1mpBurXbhHyEfNLIivMlCDxVQg6y15PjYWvQdcjKRbe1Fg7DefzvYKonbXGV/zxHDi pQwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780100594; x=1780705394; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1p04x6ZghZmLiQW4r6y7TuUkEl7HeypX+13BZ14qNiE=; b=AYEOm/G7rh4VD//bM8ajTkSylEOBfwuYDbHQl24pi55IQRIQ8HY3Qv3g4CVQTCwrfU f6fCvUcDswt7xUKRrVA7oi3NhW0r1f92B3cmXhGw2JmJ9rWj/PhEtTvEvbzFtYMD5eaM 6mXS8YnMtuON4e98s+K5KlZqe59aXiMXwNYXXHSR/Mu/A9+iDtPr3B+agw6/jt8FomvI uwRpyrIsrAm/v+LZtNHZi9RH43TRr05UwcoQI9gEpNhbtOOV4n1/ysFz1jXw3TJnOivv Dvi9mnwFnLCXyu6pCETDcFquQBppp11GcTNMgpdxbLIS8EcjwTayPMLhcHjMYN2Ojbh9 /kOg== X-Forwarded-Encrypted: i=1; AFNElJ+YSTe87ti5dDFhpfaOdEsMxnk4a0h84V7MmAKDMnKx0lsCzmZfuuixfqdEp7DjFCihjgs3YNnh6BuIqTA=@vger.kernel.org X-Gm-Message-State: AOJu0YxKzeBExoaFF8LSCgF2FdBVfYWciCVfgM3BpSjXwIOij6NsPtpY VYEjDPzzD8ZO/jh0hY0jILeIDAw8i+3fQWzReR8BwR2PghB08XEWgntqgKuU64jdLWq1PblEF+/ ODzdtir8k X-Received: from play17.prod.google.com ([2002:a17:902:e191:b0:2bd:16cc:1966]) (user=jrhilke job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2409:b0:2bf:211c:4977 with SMTP id d9443c01a7336-2bf3686ccc3mr25408265ad.36.1780100593997; Fri, 29 May 2026 17:23:13 -0700 (PDT) Date: Sat, 30 May 2026 00:21:22 +0000 In-Reply-To: <20260530002134.558837-1-jrhilke@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260530002134.558837-1-jrhilke@google.com> X-Mailer: git-send-email 2.54.0.929.g9b7fa37559-goog Message-ID: <20260530002134.558837-8-jrhilke@google.com> Subject: [PATCH v4 07/19] KVM: selftests: Verify IRQ bypass works in IRQ test From: Josh Hilke To: Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Matlack , Alex Williamson , Josh Hilke Content-Type: text/plain; charset="UTF-8" From: David Matlack Trigger interrupts from a VFIO device instead of emulating interrupts using KVM eventfds. This verifies that guests receive interrupts via IRQ bypass. Add a '-d' argument to tools/testing/selftests/kvm/irq_test which takes the segment:bus:device.function number of a PCI device bound to VFIO which will trigger interrupts. The device must have a VFIO selftest driver in order to work with the test. Example: $ ./tools/testing/selftests/kvm/irq_test -d 0000:06:0a.1 Co-developed-by: Josh Hilke Signed-off-by: Josh Hilke Signed-off-by: David Matlack --- tools/testing/selftests/kvm/irq_test.c | 61 +++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/irq_test.c b/tools/testing/selftests/kvm/irq_test.c index d3fee51cf451..616eb38c05b8 100644 --- a/tools/testing/selftests/kvm/irq_test.c +++ b/tools/testing/selftests/kvm/irq_test.c @@ -1,14 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 #include "kvm_util.h" #include "test_util.h" +#include #include "apic.h" #include "processor.h" +#include "proc_util.h" #include #include #include #include #include +#include static u64 timeout_ns = 2ULL * 1000 * 1000 * 1000; static bool guest_ready_for_irqs[KVM_MAX_VCPUS]; @@ -55,6 +58,36 @@ static void *vcpu_thread_main(void *arg) return NULL; } +static int vfio_setup_msi(struct vfio_pci_device *device) +{ + const int flags = MAP_SHARED | MAP_ANONYMOUS; + const int prot = PROT_READ | PROT_WRITE; + struct dma_region *region; + + /* A driver is required to generate an MSI. */ + TEST_REQUIRE(device->driver.ops); + + /* Set up a DMA-able region for the driver to use. */ + region = &device->driver.region; + region->iova = 0; + region->size = SZ_2M; + region->vaddr = kvm_mmap(region->size, prot, flags, -1); + TEST_ASSERT(region->vaddr != MAP_FAILED, "mmap() failed\n"); + iommu_map(device->iommu, region); + + vfio_pci_driver_init(device); + return device->driver.msi; +} + +static void trigger_interrupt(struct vfio_pci_device *device, int eventfd) +{ + if (device) + vfio_pci_driver_send_msi(device); + else + eventfd_write(eventfd, 1); +} + + static void kvm_route_msi(struct kvm_vm *vm, u32 gsi, struct kvm_vcpu *vcpu, u8 vector) { @@ -76,9 +109,10 @@ static void kvm_route_msi(struct kvm_vm *vm, u32 gsi, struct kvm_vcpu *vcpu, static void help(const char *name) { - printf("Usage: %s [-h]\n", name); + printf("Usage: %s [-d ] [-h]\n", name); printf("\n"); printf("Tests KVM IRQ injection via irqfd using an emulated eventfd.\n"); + printf("-d Use a VFIO device to send MSI-X interrupts instead of using an emulated eventfd\n"); printf("\n"); exit(KSFT_FAIL); } @@ -102,12 +136,18 @@ int main(int argc, char **argv) struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; pthread_t vcpu_threads[KVM_MAX_VCPUS]; + struct vfio_pci_device *device = NULL; int nr_irqs = 1000, nr_vcpus = 1; - int i, j, c, eventfd; + int i, j, c, msi, irq, eventfd; + const char *device_bdf = NULL; + struct iommu *iommu; struct kvm_vm *vm; - while ((c = getopt(argc, argv, "h")) != -1) { + while ((c = getopt(argc, argv, "d:h")) != -1) { switch (c) { + case 'd': + device_bdf = optarg; + break; case 'h': default: help(argv[0]); @@ -119,7 +159,17 @@ int main(int argc, char **argv) vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus); vm_install_exception_handler(vm, vector, guest_irq_handler); - eventfd = kvm_new_eventfd(); + if (device_bdf) { + iommu = iommu_init(default_iommu_mode); + device = vfio_pci_device_init(device_bdf, iommu); + msi = vfio_setup_msi(device); + irq = get_proc_vfio_irq_number(device_bdf, msi); + eventfd = device->msi_eventfds[msi]; + printf("Using device %s MSI-X[%d] (IRQ-%d)\n", device_bdf, msi, + irq); + } else { + eventfd = kvm_new_eventfd(); + } printf("Injecting interrupts for GSI %d (Vector 0x%x) %d times\n", gsi, vector, nr_irqs); @@ -147,8 +197,7 @@ int main(int argc, char **argv) "IRQ flag for vCPU %d not clear prior to test", vcpus[j]->id); - /* Trigger interrupt */ - eventfd_write(eventfd, 1); + trigger_interrupt(device, eventfd); clock_gettime(CLOCK_MONOTONIC, &start); for (;;) { -- 2.54.0.929.g9b7fa37559-goog