1139825Simp// SPDX-License-Identifier: GPL-2.0-only 2103619Sgrehan/* 3103619Sgrehan * irq_comm.c: Common API for in kernel interrupt controller 4103619Sgrehan * Copyright (c) 2007, Intel Corporation. 5103619Sgrehan * 6103619Sgrehan * Authors: 7103619Sgrehan * Yaozu (Eddie) Dong <Eddie.dong@intel.com> 8103619Sgrehan * 9103619Sgrehan * Copyright 2010 Red Hat, Inc. and/or its affiliates. 10103619Sgrehan */ 11103619Sgrehan#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12103619Sgrehan 13103619Sgrehan#include <linux/kvm_host.h> 14103619Sgrehan#include <linux/slab.h> 15103619Sgrehan#include <linux/export.h> 16103619Sgrehan#include <linux/rculist.h> 17103619Sgrehan 18103619Sgrehan#include <trace/events/kvm.h> 19103619Sgrehan 20103619Sgrehan#include "irq.h" 21103619Sgrehan 22103619Sgrehan#include "ioapic.h" 23103619Sgrehan 24103619Sgrehan#include "lapic.h" 25103619Sgrehan 26103619Sgrehan#include "hyperv.h" 27103619Sgrehan#include "x86.h" 28103619Sgrehan#include "xen.h" 29103619Sgrehan 30103619Sgrehanstatic int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, 31103619Sgrehan struct kvm *kvm, int irq_source_id, int level, 32103619Sgrehan bool line_status) 33103619Sgrehan{ 34103619Sgrehan struct kvm_pic *pic = kvm->arch.vpic; 35103619Sgrehan return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); 36103619Sgrehan} 37103619Sgrehan 38131102Sgrehanstatic int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, 39103619Sgrehan struct kvm *kvm, int irq_source_id, int level, 40103619Sgrehan bool line_status) 41103619Sgrehan{ 42103619Sgrehan struct kvm_ioapic *ioapic = kvm->arch.vioapic; 43103619Sgrehan return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level, 44209298Snwhitehorn line_status); 45209298Snwhitehorn} 46209298Snwhitehorn 47103619Sgrehanint kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, 48103619Sgrehan struct kvm_lapic_irq *irq, struct dest_map *dest_map) 49209298Snwhitehorn{ 50103619Sgrehan int r = -1; 51133589Smarius struct kvm_vcpu *vcpu, *lowest = NULL; 52153050Smarius unsigned long i, dest_vcpu_bitmap[BITS_TO_LONGS(KVM_MAX_VCPUS)]; 53103619Sgrehan unsigned int dest_vcpus = 0; 54103619Sgrehan 55103619Sgrehan if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r, dest_map)) 56103619Sgrehan return r; 57103619Sgrehan 58103619Sgrehan if (irq->dest_mode == APIC_DEST_PHYSICAL && 59103619Sgrehan irq->dest_id == 0xff && kvm_lowest_prio_delivery(irq)) { 60131400Sgrehan pr_info("apic: phys broadcast and lowest prio\n"); 61131400Sgrehan irq->delivery_mode = APIC_DM_FIXED; 62131400Sgrehan } 63131400Sgrehan 64131400Sgrehan memset(dest_vcpu_bitmap, 0, sizeof(dest_vcpu_bitmap)); 65131400Sgrehan 66131400Sgrehan kvm_for_each_vcpu(i, vcpu, kvm) { 67131400Sgrehan if (!kvm_apic_present(vcpu)) 68221519Snwhitehorn continue; 69221519Snwhitehorn 70221519Snwhitehorn if (!kvm_apic_match_dest(vcpu, src, irq->shorthand, 71221519Snwhitehorn irq->dest_id, irq->dest_mode)) 72131400Sgrehan continue; 73131400Sgrehan 74103619Sgrehan if (!kvm_lowest_prio_delivery(irq)) { 75103619Sgrehan if (r < 0) 76103619Sgrehan r = 0; 77103619Sgrehan r += kvm_apic_set_irq(vcpu, irq, dest_map); 78103619Sgrehan } else if (kvm_apic_sw_enabled(vcpu->arch.apic)) { 79103619Sgrehan if (!kvm_vector_hashing_enabled()) { 80103619Sgrehan if (!lowest) 81103619Sgrehan lowest = vcpu; 82103619Sgrehan else if (kvm_apic_compare_prio(vcpu, lowest) < 0) 83103619Sgrehan lowest = vcpu; 84103619Sgrehan } else { 85103619Sgrehan __set_bit(i, dest_vcpu_bitmap); 86103619Sgrehan dest_vcpus++; 87103619Sgrehan } 88103619Sgrehan } 89153050Smarius } 90103619Sgrehan 91103619Sgrehan if (dest_vcpus != 0) { 92103619Sgrehan int idx = kvm_vector_to_index(irq->vector, dest_vcpus, 93103619Sgrehan dest_vcpu_bitmap, KVM_MAX_VCPUS); 94103619Sgrehan 95103619Sgrehan lowest = kvm_get_vcpu(kvm, idx); 96103619Sgrehan } 97103619Sgrehan 98103619Sgrehan if (lowest) 99103619Sgrehan r = kvm_apic_set_irq(lowest, irq, dest_map); 100103619Sgrehan 101103619Sgrehan return r; 102103619Sgrehan} 103103619Sgrehan 104103619Sgrehanvoid kvm_set_msi_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, 105103619Sgrehan struct kvm_lapic_irq *irq) 106103619Sgrehan{ 107103619Sgrehan struct msi_msg msg = { .address_lo = e->msi.address_lo, 108103619Sgrehan .address_hi = e->msi.address_hi, 109103619Sgrehan .data = e->msi.data }; 110103619Sgrehan 111103619Sgrehan trace_kvm_msi_set_irq(msg.address_lo | (kvm->arch.x2apic_format ? 112103619Sgrehan (u64)msg.address_hi << 32 : 0), msg.data); 113103619Sgrehan 114103619Sgrehan irq->dest_id = x86_msi_msg_get_destid(&msg, kvm->arch.x2apic_format); 115186128Snwhitehorn irq->vector = msg.arch_data.vector; 116186128Snwhitehorn irq->dest_mode = kvm_lapic_irq_dest_mode(msg.arch_addr_lo.dest_mode_logical); 117133589Smarius irq->trig_mode = msg.arch_data.is_level; 118153050Smarius irq->delivery_mode = msg.arch_data.delivery_mode << 8; 119153050Smarius irq->msi_redir_hint = msg.arch_addr_lo.redirect_hint; 120153050Smarius irq->level = 1; 121153050Smarius irq->shorthand = APIC_DEST_NOSHORT; 122153050Smarius} 123153050SmariusEXPORT_SYMBOL_GPL(kvm_set_msi_irq); 124133589Smarius 125103619Sgrehanstatic inline bool kvm_msi_route_invalid(struct kvm *kvm, 126103619Sgrehan struct kvm_kernel_irq_routing_entry *e) 127103619Sgrehan{ 128103619Sgrehan return kvm->arch.x2apic_format && (e->msi.address_hi & 0xff); 129103619Sgrehan} 130103619Sgrehan 131103619Sgrehanint kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, 132103619Sgrehan struct kvm *kvm, int irq_source_id, int level, bool line_status) 133103619Sgrehan{ 134103619Sgrehan struct kvm_lapic_irq irq; 135103619Sgrehan 136103619Sgrehan if (kvm_msi_route_invalid(kvm, e)) 137103619Sgrehan return -EINVAL; 138103619Sgrehan 139103619Sgrehan if (!level) 140103619Sgrehan return -1; 141103619Sgrehan 142103619Sgrehan kvm_set_msi_irq(kvm, e, &irq); 143103619Sgrehan 144103619Sgrehan return kvm_irq_delivery_to_apic(kvm, NULL, &irq, NULL); 145112428Sgrehan} 146112428Sgrehan 147103619Sgrehan#ifdef CONFIG_KVM_HYPERV 148112428Sgrehanstatic int kvm_hv_set_sint(struct kvm_kernel_irq_routing_entry *e, 149183882Snwhitehorn struct kvm *kvm, int irq_source_id, int level, 150183882Snwhitehorn bool line_status) 151112428Sgrehan{ 152103619Sgrehan if (!level) 153103619Sgrehan return -1; 154103619Sgrehan 155103619Sgrehan return kvm_hv_synic_set_irq(kvm, e->hv_sint.vcpu, e->hv_sint.sint); 156103619Sgrehan} 157103619Sgrehan#endif 158108991Sbenno 159108991Sbennoint kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, 160186805Snwhitehorn struct kvm *kvm, int irq_source_id, int level, 161108991Sbenno bool line_status) 162108991Sbenno{ 163108991Sbenno struct kvm_lapic_irq irq; 164108991Sbenno int r; 165103619Sgrehan 166103619Sgrehan switch (e->type) { 167108991Sbenno#ifdef CONFIG_KVM_HYPERV 168108991Sbenno case KVM_IRQ_ROUTING_HV_SINT: 169108991Sbenno return kvm_hv_set_sint(e, kvm, irq_source_id, level, 170108991Sbenno line_status); 171186805Snwhitehorn#endif 172186805Snwhitehorn 173186805Snwhitehorn case KVM_IRQ_ROUTING_MSI: 174108991Sbenno if (kvm_msi_route_invalid(kvm, e)) 175108991Sbenno return -EINVAL; 176103619Sgrehan 177108991Sbenno kvm_set_msi_irq(kvm, e, &irq); 178103619Sgrehan 179108991Sbenno if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL)) 180103619Sgrehan return r; 181108991Sbenno break; 182108991Sbenno 183108991Sbenno#ifdef CONFIG_KVM_XEN 184103619Sgrehan case KVM_IRQ_ROUTING_XEN_EVTCHN: 185103619Sgrehan if (!level) 186103619Sgrehan return -1; 187103619Sgrehan 188103619Sgrehan return kvm_xen_set_evtchn_fast(&e->xen_evtchn, kvm); 189103619Sgrehan#endif 190103619Sgrehan default: 191103619Sgrehan break; 192103619Sgrehan } 193103619Sgrehan 194209298Snwhitehorn return -EWOULDBLOCK; 195178599Smarcel} 196178599Smarcel 197178599Smarcelint kvm_request_irq_source_id(struct kvm *kvm) 198108991Sbenno{ 199178599Smarcel unsigned long *bitmap = &kvm->arch.irq_sources_bitmap; 200178599Smarcel int irq_source_id; 201108991Sbenno 202108991Sbenno mutex_lock(&kvm->irq_lock); 203108991Sbenno irq_source_id = find_first_zero_bit(bitmap, BITS_PER_LONG); 204186728Snwhitehorn 205186728Snwhitehorn if (irq_source_id >= BITS_PER_LONG) { 206186728Snwhitehorn pr_warn("exhausted allocatable IRQ sources!\n"); 207178599Smarcel irq_source_id = -EFAULT; 208178599Smarcel goto unlock; 209178599Smarcel } 210178599Smarcel 211178599Smarcel ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); 212178599Smarcel ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); 213178599Smarcel set_bit(irq_source_id, bitmap); 214108991Sbennounlock: 215108991Sbenno mutex_unlock(&kvm->irq_lock); 216108991Sbenno 217178599Smarcel return irq_source_id; 218108991Sbenno} 219108991Sbenno 220209298Snwhitehornvoid kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) 221209298Snwhitehorn{ 222209298Snwhitehorn ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); 223209298Snwhitehorn ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); 224178599Smarcel 225218184Smarcel mutex_lock(&kvm->irq_lock); 226218184Smarcel if (irq_source_id < 0 || 227178599Smarcel irq_source_id >= BITS_PER_LONG) { 228218184Smarcel pr_err("IRQ source ID out of range!\n"); 229108991Sbenno goto unlock; 230218184Smarcel } 231178599Smarcel clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap); 232178599Smarcel if (!irqchip_kernel(kvm)) 233103619Sgrehan goto unlock; 234103619Sgrehan 235103619Sgrehan kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id); 236103619Sgrehan kvm_pic_clear_all(kvm->arch.vpic, irq_source_id); 237103619Sgrehanunlock: 238103619Sgrehan mutex_unlock(&kvm->irq_lock); 239110080Sbenno} 240110080Sbenno 241110080Sbennovoid kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, 242110080Sbenno struct kvm_irq_mask_notifier *kimn) 243110080Sbenno{ 244110080Sbenno mutex_lock(&kvm->irq_lock); 245110080Sbenno kimn->irq = irq; 246110080Sbenno hlist_add_head_rcu(&kimn->link, &kvm->arch.mask_notifier_list); 247110080Sbenno mutex_unlock(&kvm->irq_lock); 248110080Sbenno} 249110080Sbenno 250103619Sgrehanvoid kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, 251103619Sgrehan struct kvm_irq_mask_notifier *kimn) 252103619Sgrehan{ 253103619Sgrehan mutex_lock(&kvm->irq_lock); 254103619Sgrehan hlist_del_rcu(&kimn->link); 255103619Sgrehan mutex_unlock(&kvm->irq_lock); 256103619Sgrehan synchronize_srcu(&kvm->irq_srcu); 257103619Sgrehan} 258103619Sgrehan 259103619Sgrehanvoid kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, 260103619Sgrehan bool mask) 261103619Sgrehan{ 262103619Sgrehan struct kvm_irq_mask_notifier *kimn; 263103619Sgrehan int idx, gsi; 264103619Sgrehan 265103619Sgrehan idx = srcu_read_lock(&kvm->irq_srcu); 266103619Sgrehan gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); 267103619Sgrehan if (gsi != -1) 268103619Sgrehan hlist_for_each_entry_rcu(kimn, &kvm->arch.mask_notifier_list, link) 269103619Sgrehan if (kimn->irq == gsi) 270103619Sgrehan kimn->func(kimn, mask); 271103619Sgrehan srcu_read_unlock(&kvm->irq_srcu, idx); 272103619Sgrehan} 273103619Sgrehan 274133862Smariusbool kvm_arch_can_set_irq_routing(struct kvm *kvm) 275103619Sgrehan{ 276103619Sgrehan return irqchip_in_kernel(kvm); 277103619Sgrehan} 278103619Sgrehan 279103619Sgrehanint kvm_set_routing_entry(struct kvm *kvm, 280103619Sgrehan struct kvm_kernel_irq_routing_entry *e, 281103619Sgrehan const struct kvm_irq_routing_entry *ue) 282103619Sgrehan{ 283103619Sgrehan /* We can't check irqchip_in_kernel() here as some callers are 284108991Sbenno * currently initializing the irqchip. Other callers should therefore 285103619Sgrehan * check kvm_arch_can_set_irq_routing() before calling this function. 286103619Sgrehan */ 287179746Skevlo switch (ue->type) { 288103619Sgrehan case KVM_IRQ_ROUTING_IRQCHIP: 289103619Sgrehan if (irqchip_split(kvm)) 290183882Snwhitehorn return -EINVAL; 291103619Sgrehan e->irqchip.pin = ue->u.irqchip.pin; 292103619Sgrehan switch (ue->u.irqchip.irqchip) { 293103619Sgrehan case KVM_IRQCHIP_PIC_SLAVE: 294103619Sgrehan e->irqchip.pin += PIC_NUM_PINS / 2; 295103619Sgrehan fallthrough; 296103619Sgrehan case KVM_IRQCHIP_PIC_MASTER: 297103619Sgrehan if (ue->u.irqchip.pin >= PIC_NUM_PINS / 2) 298103619Sgrehan return -EINVAL; 299103619Sgrehan e->set = kvm_set_pic_irq; 300103619Sgrehan break; 301103619Sgrehan case KVM_IRQCHIP_IOAPIC: 302103619Sgrehan if (ue->u.irqchip.pin >= KVM_IOAPIC_NUM_PINS) 303221519Snwhitehorn return -EINVAL; 304221519Snwhitehorn e->set = kvm_set_ioapic_irq; 305221519Snwhitehorn break; 306221519Snwhitehorn default: 307103619Sgrehan return -EINVAL; 308110080Sbenno } 309179746Skevlo e->irqchip.irqchip = ue->u.irqchip.irqchip; 310179746Skevlo break; 311179746Skevlo case KVM_IRQ_ROUTING_MSI: 312179746Skevlo e->set = kvm_set_msi; 313179746Skevlo e->msi.address_lo = ue->u.msi.address_lo; 314179746Skevlo e->msi.address_hi = ue->u.msi.address_hi; 315179746Skevlo e->msi.data = ue->u.msi.data; 316103619Sgrehan 317179746Skevlo if (kvm_msi_route_invalid(kvm, e)) 318179746Skevlo return -EINVAL; 319103619Sgrehan break; 320103619Sgrehan#ifdef CONFIG_KVM_HYPERV 321103619Sgrehan case KVM_IRQ_ROUTING_HV_SINT: 322103619Sgrehan e->set = kvm_hv_set_sint; 323103619Sgrehan e->hv_sint.vcpu = ue->u.hv_sint.vcpu; 324103619Sgrehan e->hv_sint.sint = ue->u.hv_sint.sint; 325153050Smarius break; 326153050Smarius#endif 327153050Smarius#ifdef CONFIG_KVM_XEN 328153050Smarius case KVM_IRQ_ROUTING_XEN_EVTCHN: 329153050Smarius return kvm_xen_setup_evtchn(kvm, e, ue); 330153050Smarius#endif 331153050Smarius default: 332108991Sbenno return -EINVAL; 333153050Smarius } 334153050Smarius 335103619Sgrehan return 0; 336103619Sgrehan} 337153050Smarius 338153050Smariusbool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq, 339153050Smarius struct kvm_vcpu **dest_vcpu) 340186805Snwhitehorn{ 341186805Snwhitehorn int r = 0; 342186805Snwhitehorn unsigned long i; 343186805Snwhitehorn struct kvm_vcpu *vcpu; 344153050Smarius 345153050Smarius if (kvm_intr_is_single_vcpu_fast(kvm, irq, dest_vcpu)) 346153050Smarius return true; 347153050Smarius 348103619Sgrehan kvm_for_each_vcpu(i, vcpu, kvm) { 349153050Smarius if (!kvm_apic_present(vcpu)) 350153050Smarius continue; 351153050Smarius 352153050Smarius if (!kvm_apic_match_dest(vcpu, NULL, irq->shorthand, 353153050Smarius irq->dest_id, irq->dest_mode)) 354153050Smarius continue; 355153050Smarius 356103619Sgrehan if (++r == 2) 357153050Smarius return false; 358221519Snwhitehorn 359221519Snwhitehorn *dest_vcpu = vcpu; 360221519Snwhitehorn } 361221519Snwhitehorn 362221519Snwhitehorn return r == 1; 363221519Snwhitehorn} 364221519SnwhitehornEXPORT_SYMBOL_GPL(kvm_intr_is_single_vcpu); 365221519Snwhitehorn 366221519Snwhitehorn#define IOAPIC_ROUTING_ENTRY(irq) \ 367221519Snwhitehorn { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ 368221519Snwhitehorn .u.irqchip = { .irqchip = KVM_IRQCHIP_IOAPIC, .pin = (irq) } } 369221519Snwhitehorn#define ROUTING_ENTRY1(irq) IOAPIC_ROUTING_ENTRY(irq) 370221519Snwhitehorn 371221519Snwhitehorn#define PIC_ROUTING_ENTRY(irq) \ 372221519Snwhitehorn { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ 373221519Snwhitehorn .u.irqchip = { .irqchip = SELECT_PIC(irq), .pin = (irq) % 8 } } 374221519Snwhitehorn#define ROUTING_ENTRY2(irq) \ 375221519Snwhitehorn IOAPIC_ROUTING_ENTRY(irq), PIC_ROUTING_ENTRY(irq) 376221519Snwhitehorn 377221519Snwhitehornstatic const struct kvm_irq_routing_entry default_routing[] = { 378221519Snwhitehorn ROUTING_ENTRY2(0), ROUTING_ENTRY2(1), 379221519Snwhitehorn ROUTING_ENTRY2(2), ROUTING_ENTRY2(3), 380221519Snwhitehorn ROUTING_ENTRY2(4), ROUTING_ENTRY2(5), 381103619Sgrehan ROUTING_ENTRY2(6), ROUTING_ENTRY2(7), 382103619Sgrehan ROUTING_ENTRY2(8), ROUTING_ENTRY2(9), 383103619Sgrehan ROUTING_ENTRY2(10), ROUTING_ENTRY2(11), 384103619Sgrehan ROUTING_ENTRY2(12), ROUTING_ENTRY2(13), 385103619Sgrehan ROUTING_ENTRY2(14), ROUTING_ENTRY2(15), 386103619Sgrehan ROUTING_ENTRY1(16), ROUTING_ENTRY1(17), 387103619Sgrehan ROUTING_ENTRY1(18), ROUTING_ENTRY1(19), 388103619Sgrehan ROUTING_ENTRY1(20), ROUTING_ENTRY1(21), 389103619Sgrehan ROUTING_ENTRY1(22), ROUTING_ENTRY1(23), 390103619Sgrehan}; 391103619Sgrehan 392103619Sgrehanint kvm_setup_default_irq_routing(struct kvm *kvm) 393103619Sgrehan{ 394103619Sgrehan return kvm_set_irq_routing(kvm, default_routing, 395103619Sgrehan ARRAY_SIZE(default_routing), 0); 396103619Sgrehan} 397103619Sgrehan 398103619Sgrehanstatic const struct kvm_irq_routing_entry empty_routing[] = {}; 399103619Sgrehan 400103619Sgrehanint kvm_setup_empty_irq_routing(struct kvm *kvm) 401103619Sgrehan{ 402103619Sgrehan return kvm_set_irq_routing(kvm, empty_routing, 0, 0); 403103619Sgrehan} 404103619Sgrehan 405103619Sgrehanvoid kvm_arch_post_irq_routing_update(struct kvm *kvm) 406103619Sgrehan{ 407103619Sgrehan if (!irqchip_split(kvm)) 408103619Sgrehan return; 409103619Sgrehan kvm_make_scan_ioapic_request(kvm); 410103619Sgrehan} 411110080Sbenno 412110080Sbennovoid kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, 413133589Smarius ulong *ioapic_handled_vectors) 414103619Sgrehan{ 415103619Sgrehan struct kvm *kvm = vcpu->kvm; 416110080Sbenno struct kvm_kernel_irq_routing_entry *entry; 417110080Sbenno struct kvm_irq_routing_table *table; 418103619Sgrehan u32 i, nr_ioapic_pins; 419133589Smarius int idx; 420133589Smarius 421133589Smarius idx = srcu_read_lock(&kvm->irq_srcu); 422110080Sbenno table = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); 423110080Sbenno nr_ioapic_pins = min_t(u32, table->nr_rt_entries, 424110080Sbenno kvm->arch.nr_reserved_ioapic_pins); 425103619Sgrehan for (i = 0; i < nr_ioapic_pins; ++i) { 426103619Sgrehan hlist_for_each_entry(entry, &table->map[i], link) { 427103619Sgrehan struct kvm_lapic_irq irq; 428103619Sgrehan 429103619Sgrehan if (entry->type != KVM_IRQ_ROUTING_MSI) 430103619Sgrehan continue; 431103619Sgrehan 432103619Sgrehan kvm_set_msi_irq(vcpu->kvm, entry, &irq); 433110080Sbenno 434110080Sbenno if (irq.trig_mode && 435110080Sbenno (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT, 436110080Sbenno irq.dest_id, irq.dest_mode) || 437110080Sbenno kvm_apic_pending_eoi(vcpu, irq.vector))) 438110080Sbenno __set_bit(irq.vector, ioapic_handled_vectors); 439110080Sbenno } 440103619Sgrehan } 441103619Sgrehan srcu_read_unlock(&kvm->irq_srcu, idx); 442108994Sbenno} 443103619Sgrehan 444103619Sgrehanvoid kvm_arch_irq_routing_update(struct kvm *kvm) 445103619Sgrehan{ 446103619Sgrehan#ifdef CONFIG_KVM_HYPERV 447103619Sgrehan kvm_hv_irq_routing_update(kvm); 448103619Sgrehan#endif 449103619Sgrehan} 450110080Sbenno