^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * irqchip.c: Common API for in kernel interrupt controllers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2007, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2010 Red Hat, Inc. and/or its affiliates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2013, Alexander Graf <agraf@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is derived from virt/kvm/irq_comm.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Alexander Graf <agraf@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kvm_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/srcu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <trace/events/kvm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "irq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int kvm_irq_map_gsi(struct kvm *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct kvm_kernel_irq_routing_entry *entries, int gsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct kvm_irq_routing_table *irq_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct kvm_kernel_irq_routing_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) lockdep_is_held(&kvm->irq_lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (irq_rt && gsi < irq_rt->nr_rt_entries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) entries[n] = *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ++n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct kvm_irq_routing_table *irq_rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return irq_rt->chip[irqchip][pin];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct kvm_kernel_irq_routing_entry route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (!irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) route.msi.address_lo = msi->address_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) route.msi.address_hi = msi->address_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) route.msi.data = msi->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) route.msi.flags = msi->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) route.msi.devid = msi->devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Return value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * < 0 Interrupt was ignored (masked or not delivered for other reasons)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * = 0 Interrupt was coalesced (previous irq is still pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * > 0 Number of CPUs interrupt was delivered to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) bool line_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int ret = -1, i, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) trace_kvm_set_irq(irq, level, irq_source_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Not possible to detect if the guest uses the PIC or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * IOAPIC. So set the bit in both. The guest will ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * writes to the unused one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) idx = srcu_read_lock(&kvm->irq_srcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) i = kvm_irq_map_gsi(kvm, irq_set, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) srcu_read_unlock(&kvm->irq_srcu, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) while (i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) line_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ret = r + ((ret < 0) ? 0 : ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void free_irq_routing_table(struct kvm_irq_routing_table *rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) for (i = 0; i < rt->nr_rt_entries; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct kvm_kernel_irq_routing_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct hlist_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) hlist_for_each_entry_safe(e, n, &rt->map[i], link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) hlist_del(&e->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) kfree(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) kfree(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) void kvm_free_irq_routing(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* Called only during vm destruction. Nobody can use the pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) at this stage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct kvm_irq_routing_table *rt = rcu_access_pointer(kvm->irq_routing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) free_irq_routing_table(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int setup_routing_entry(struct kvm *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct kvm_irq_routing_table *rt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct kvm_kernel_irq_routing_entry *e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const struct kvm_irq_routing_entry *ue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct kvm_kernel_irq_routing_entry *ei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 gsi = array_index_nospec(ue->gsi, KVM_MAX_IRQ_ROUTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Do not allow GSI to be mapped to the same irqchip more than once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Allow only one to one mapping between GSI and non-irqchip routing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) hlist_for_each_entry(ei, &rt->map[gsi], link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (ei->type != KVM_IRQ_ROUTING_IRQCHIP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ue->type != KVM_IRQ_ROUTING_IRQCHIP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ue->u.irqchip.irqchip == ei->irqchip.irqchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) e->gsi = gsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) e->type = ue->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) r = kvm_set_routing_entry(kvm, e, ue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (e->type == KVM_IRQ_ROUTING_IRQCHIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) rt->chip[e->irqchip.irqchip][e->irqchip.pin] = e->gsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) hlist_add_head(&e->link, &rt->map[e->gsi]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) void __attribute__((weak)) kvm_arch_irq_routing_update(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) bool __weak kvm_arch_can_set_irq_routing(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int kvm_set_irq_routing(struct kvm *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const struct kvm_irq_routing_entry *ue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct kvm_irq_routing_table *new, *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct kvm_kernel_irq_routing_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u32 i, j, nr_rt_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) for (i = 0; i < nr; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ue[i].gsi >= KVM_MAX_IRQ_ROUTES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) nr_rt_entries = max(nr_rt_entries, ue[i].gsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) nr_rt_entries += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) new = kzalloc(struct_size(new, map, nr_rt_entries), GFP_KERNEL_ACCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) new->nr_rt_entries = nr_rt_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) for (i = 0; i < KVM_NR_IRQCHIPS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) for (j = 0; j < KVM_IRQCHIP_NUM_PINS; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) new->chip[i][j] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) for (i = 0; i < nr; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) r = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) e = kzalloc(sizeof(*e), GFP_KERNEL_ACCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) r = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) switch (ue->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case KVM_IRQ_ROUTING_MSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (ue->flags & ~KVM_MSI_VALID_DEVID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto free_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (ue->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) goto free_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) r = setup_routing_entry(kvm, new, e, ue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) goto free_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ++ue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) mutex_lock(&kvm->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) old = rcu_dereference_protected(kvm->irq_routing, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) rcu_assign_pointer(kvm->irq_routing, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) kvm_irq_routing_update(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) kvm_arch_irq_routing_update(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) mutex_unlock(&kvm->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) kvm_arch_post_irq_routing_update(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) synchronize_srcu_expedited(&kvm->irq_srcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) new = old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) free_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) kfree(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) free_irq_routing_table(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }