/* * Accelerated irqchip abstraction * * Copyright Microsoft, Corp. 2025 * * Authors: Ziqiao Zhou * Magnus Kulke * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "hw/pci/msi.h" #include "system/kvm.h" #include "system/mshv.h" #include "system/accel-irq.h" int accel_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice *dev) { if (mshv_msi_via_irqfd_enabled()) { return mshv_irqchip_add_msi_route(c, vector, dev); } if (kvm_enabled()) { return kvm_irqchip_add_msi_route(c, vector, dev); } return -ENOSYS; } int accel_irqchip_update_msi_route(int vector, MSIMessage msg, PCIDevice *dev) { if (mshv_msi_via_irqfd_enabled()) { return mshv_irqchip_update_msi_route(vector, msg, dev); } if (kvm_enabled()) { return kvm_irqchip_update_msi_route(kvm_state, vector, msg, dev); } return -ENOSYS; } void accel_irqchip_commit_route_changes(AccelRouteChange *c) { if (c->changes) { accel_irqchip_commit_routes(); c->changes = 0; } } void accel_irqchip_commit_routes(void) { if (mshv_msi_via_irqfd_enabled()) { mshv_irqchip_commit_routes(mshv_state); } if (kvm_enabled()) { kvm_irqchip_commit_routes(kvm_state); } } void accel_irqchip_release_virq(int virq) { if (mshv_msi_via_irqfd_enabled()) { mshv_irqchip_release_virq(mshv_state, virq); } if (kvm_enabled()) { kvm_irqchip_release_virq(kvm_state, virq); } } int accel_irqchip_add_irqfd_notifier_gsi(EventNotifier *n, EventNotifier *rn, int virq) { if (mshv_msi_via_irqfd_enabled()) { return mshv_irqchip_add_irqfd_notifier_gsi(n, rn, virq); } if (kvm_enabled()) { return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, rn, virq); } return -ENOSYS; } int accel_irqchip_remove_irqfd_notifier_gsi(EventNotifier *n, int virq) { if (mshv_msi_via_irqfd_enabled()) { return mshv_irqchip_remove_irqfd_notifier_gsi(n, virq); } if (kvm_enabled()) { return kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, virq); } return -ENOSYS; } inline AccelRouteChange accel_irqchip_begin_route_changes(void) { if (mshv_msi_via_irqfd_enabled()) { return (AccelRouteChange) { .accel = ACCEL(mshv_state), .changes = 0, }; } if (kvm_enabled()) { return (AccelRouteChange) { .accel = ACCEL(kvm_state), .changes = 0, }; } error_report("can't initiate route change, no accel irqchip available"); abort(); }