Lines Matching +full:sw +full:- +full:managed
1 // SPDX-License-Identifier: GPL-2.0-only
11 #include <linux/irqchip/arm-gic-v3.h>
18 * The vgic-v4 layer acts as a bridge between several entities:
19 * - The GICv4 ITS representation offered by the ITS driver
20 * - VFIO, which is in charge of the PCI endpoint
21 * - The virtual ITS, which is the only thing the guest sees
46 * - Any invalidation triggers a call to its_prop_update_vlpi()
47 * - The INT command results in a irq_set_irqchip_state(), which
49 * - The CLEAR command results in a irq_set_irqchip_state(), which
51 * - DISCARD translates into an unmap, similar to a call to
53 * - MOVI is translated by an update of the existing mapping, changing
55 * - MOVALL is translated by a string of mapping updates (similar to
61 * will get the interrupt via the normal SW injection). Fixing this is
71 * You must be in a non-preemptible context. On exit, a call to
90 !irqd_irq_disabled(&irq_to_desc(irq)->irq_data)) in vgic_v4_doorbell_handler()
95 * made non-resident. Ensure we only update pending_last in vgic_v4_doorbell_handler()
96 * *after* the non-residency sequence has completed. in vgic_v4_doorbell_handler()
98 raw_spin_lock(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vpe_lock); in vgic_v4_doorbell_handler()
99 vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true; in vgic_v4_doorbell_handler()
100 raw_spin_unlock(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vpe_lock); in vgic_v4_doorbell_handler()
110 vpe->sgi_config[irq->intid].enabled = irq->enabled; in vgic_v4_sync_sgi_config()
111 vpe->sgi_config[irq->intid].group = irq->group; in vgic_v4_sync_sgi_config()
112 vpe->sgi_config[irq->intid].priority = irq->priority; in vgic_v4_sync_sgi_config()
117 struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; in vgic_v4_enable_vsgis()
131 raw_spin_lock_irqsave(&irq->irq_lock, flags); in vgic_v4_enable_vsgis()
133 if (irq->hw) in vgic_v4_enable_vsgis()
136 irq->hw = true; in vgic_v4_enable_vsgis()
137 irq->host_irq = irq_find_mapping(vpe->sgi_domain, i); in vgic_v4_enable_vsgis()
141 desc = irq_to_desc(irq->host_irq); in vgic_v4_enable_vsgis()
146 ret = irq_set_irqchip_state(irq->host_irq, in vgic_v4_enable_vsgis()
148 irq->pending_latch); in vgic_v4_enable_vsgis()
150 irq->pending_latch = false; in vgic_v4_enable_vsgis()
153 raw_spin_unlock_irqrestore(&irq->irq_lock, flags); in vgic_v4_enable_vsgis()
154 vgic_put_irq(vcpu->kvm, irq); in vgic_v4_enable_vsgis()
168 raw_spin_lock_irqsave(&irq->irq_lock, flags); in vgic_v4_disable_vsgis()
170 if (!irq->hw) in vgic_v4_disable_vsgis()
173 irq->hw = false; in vgic_v4_disable_vsgis()
174 ret = irq_get_irqchip_state(irq->host_irq, in vgic_v4_disable_vsgis()
176 &irq->pending_latch); in vgic_v4_disable_vsgis()
179 desc = irq_to_desc(irq->host_irq); in vgic_v4_disable_vsgis()
182 raw_spin_unlock_irqrestore(&irq->irq_lock, flags); in vgic_v4_disable_vsgis()
183 vgic_put_irq(vcpu->kvm, irq); in vgic_v4_disable_vsgis()
189 struct vgic_dist *dist = &kvm->arch.vgic; in vgic_v4_configure_vsgis()
193 lockdep_assert_held(&kvm->arch.config_lock); in vgic_v4_configure_vsgis()
198 if (dist->nassgireq) in vgic_v4_configure_vsgis()
215 struct its_vpe *vpe = &irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe; in vgic_v4_get_vlpi_state()
216 int mask = BIT(irq->intid % BITS_PER_BYTE); in vgic_v4_get_vlpi_state()
220 va = page_address(vpe->vpt_page); in vgic_v4_get_vlpi_state()
221 ptr = va + irq->intid / BITS_PER_BYTE; in vgic_v4_get_vlpi_state()
232 * vgic_v4_init - Initialize the GICv4 data structures
241 struct vgic_dist *dist = &kvm->arch.vgic; in vgic_v4_init()
246 lockdep_assert_held(&kvm->arch.config_lock); in vgic_v4_init()
251 if (dist->its_vm.vpes) in vgic_v4_init()
254 nr_vcpus = atomic_read(&kvm->online_vcpus); in vgic_v4_init()
256 dist->its_vm.vpes = kcalloc(nr_vcpus, sizeof(*dist->its_vm.vpes), in vgic_v4_init()
258 if (!dist->its_vm.vpes) in vgic_v4_init()
259 return -ENOMEM; in vgic_v4_init()
261 dist->its_vm.nr_vpes = nr_vcpus; in vgic_v4_init()
264 dist->its_vm.vpes[i] = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; in vgic_v4_init()
266 ret = its_alloc_vcpu_irqs(&dist->its_vm); in vgic_v4_init()
269 kfree(dist->its_vm.vpes); in vgic_v4_init()
270 dist->its_vm.nr_vpes = 0; in vgic_v4_init()
271 dist->its_vm.vpes = NULL; in vgic_v4_init()
276 int irq = dist->its_vm.vpes[i]->irq; in vgic_v4_init()
286 * On GICv4.1, the doorbell is managed in HW and must in vgic_v4_init()
300 dist->its_vm.nr_vpes = i; in vgic_v4_init()
312 * vgic_v4_teardown - Free the GICv4 data structures
317 struct its_vm *its_vm = &kvm->arch.vgic.its_vm; in vgic_v4_teardown()
320 lockdep_assert_held(&kvm->arch.config_lock); in vgic_v4_teardown()
322 if (!its_vm->vpes) in vgic_v4_teardown()
325 for (i = 0; i < its_vm->nr_vpes; i++) { in vgic_v4_teardown()
327 int irq = its_vm->vpes[i]->irq; in vgic_v4_teardown()
334 kfree(its_vm->vpes); in vgic_v4_teardown()
335 its_vm->nr_vpes = 0; in vgic_v4_teardown()
336 its_vm->vpes = NULL; in vgic_v4_teardown()
341 struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; in vgic_v4_put()
343 if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident) in vgic_v4_put()
351 struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; in vgic_v4_load()
354 if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident) in vgic_v4_load()
363 * doc in drivers/irqchip/irq-gic-v4.c to understand how this in vgic_v4_load()
366 err = irq_set_affinity(vpe->irq, cpumask_of(smp_processor_id())); in vgic_v4_load()
370 err = its_make_vpe_resident(vpe, false, vcpu->kvm->arch.vgic.enabled); in vgic_v4_load()
380 err = irq_set_irqchip_state(vpe->irq, IRQCHIP_STATE_PENDING, false); in vgic_v4_load()
387 struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; in vgic_v4_commit()
393 if (!vpe->ready) in vgic_v4_commit()
401 .address_lo = irq_entry->msi.address_lo, in vgic_get_its()
402 .address_hi = irq_entry->msi.address_hi, in vgic_get_its()
403 .data = irq_entry->msi.data, in vgic_get_its()
404 .flags = irq_entry->msi.flags, in vgic_get_its()
405 .devid = irq_entry->msi.devid, in vgic_get_its()
431 mutex_lock(&its->its_lock); in kvm_vgic_v4_set_forwarding()
433 /* Perform the actual DevID/EventID -> LPI translation. */ in kvm_vgic_v4_set_forwarding()
434 ret = vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid, in kvm_vgic_v4_set_forwarding()
435 irq_entry->msi.data, &irq); in kvm_vgic_v4_set_forwarding()
440 if (irq->hw) in kvm_vgic_v4_set_forwarding()
450 .vm = &kvm->arch.vgic.its_vm, in kvm_vgic_v4_set_forwarding()
451 .vpe = &irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe, in kvm_vgic_v4_set_forwarding()
452 .vintid = irq->intid, in kvm_vgic_v4_set_forwarding()
453 .properties = ((irq->priority & 0xfc) | in kvm_vgic_v4_set_forwarding()
454 (irq->enabled ? LPI_PROP_ENABLED : 0) | in kvm_vgic_v4_set_forwarding()
463 irq->hw = true; in kvm_vgic_v4_set_forwarding()
464 irq->host_irq = virq; in kvm_vgic_v4_set_forwarding()
465 atomic_inc(&map.vpe->vlpi_count); in kvm_vgic_v4_set_forwarding()
468 raw_spin_lock_irqsave(&irq->irq_lock, flags); in kvm_vgic_v4_set_forwarding()
469 if (irq->pending_latch) { in kvm_vgic_v4_set_forwarding()
470 ret = irq_set_irqchip_state(irq->host_irq, in kvm_vgic_v4_set_forwarding()
472 irq->pending_latch); in kvm_vgic_v4_set_forwarding()
473 WARN_RATELIMIT(ret, "IRQ %d", irq->host_irq); in kvm_vgic_v4_set_forwarding()
479 irq->pending_latch = false; in kvm_vgic_v4_set_forwarding()
482 raw_spin_unlock_irqrestore(&irq->irq_lock, flags); in kvm_vgic_v4_set_forwarding()
486 mutex_unlock(&its->its_lock); in kvm_vgic_v4_set_forwarding()
508 mutex_lock(&its->its_lock); in kvm_vgic_v4_unset_forwarding()
510 ret = vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid, in kvm_vgic_v4_unset_forwarding()
511 irq_entry->msi.data, &irq); in kvm_vgic_v4_unset_forwarding()
515 WARN_ON(!(irq->hw && irq->host_irq == virq)); in kvm_vgic_v4_unset_forwarding()
516 if (irq->hw) { in kvm_vgic_v4_unset_forwarding()
517 atomic_dec(&irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count); in kvm_vgic_v4_unset_forwarding()
518 irq->hw = false; in kvm_vgic_v4_unset_forwarding()
523 mutex_unlock(&its->its_lock); in kvm_vgic_v4_unset_forwarding()