From: Sean Christopherson <seanjc@google.com>
To: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>,
Paolo Bonzini <pbonzini@redhat.com>,
Joerg Roedel <joro@8bytes.org>,
David Woodhouse <dwmw2@infradead.org>,
Lu Baolu <baolu.lu@linux.intel.com>,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
kvm@vger.kernel.org, iommu@lists.linux.dev,
linux-kernel@vger.kernel.org, Sairaj Kodilkar <sarunkod@amd.com>,
Vasant Hegde <vasant.hegde@amd.com>,
Maxim Levitsky <mlevitsk@redhat.com>,
Joao Martins <joao.m.martins@oracle.com>,
Francesco Lavra <francescolavra.fl@gmail.com>,
David Matlack <dmatlack@google.com>
Subject: Re: [PATCH v3 02/62] KVM: arm64: WARN if unmapping vLPI fails
Date: Thu, 12 Jun 2025 07:34:35 -0700 [thread overview]
Message-ID: <aErlezuoFJ8u0ue-@google.com> (raw)
In-Reply-To: <86tt4lcgs3.wl-maz@kernel.org>
On Thu, Jun 12, 2025, Marc Zyngier wrote:
> On Wed, 11 Jun 2025 23:45:05 +0100,
> Sean Christopherson <seanjc@google.com> wrote:
> >
> > WARN if unmapping a vLPI in kvm_vgic_v4_unset_forwarding() fails, as
> > failure means an IRTE has likely been left in a bad state, i.e. IRQs
> > won't go where they should.
>
> I have no idea what an IRTE is.
Sorry, x86 IOMMU terminology (Interrupt Remapping Table Entry). I think the GIC
terminology would be ITS entry? Or maybe ITS mapping?
> But not having an VLPI mapping for an interrupt at the point where we're
> tearing down the forwarding is pretty benign. IRQs *still* go where they
> should, and we don't lose anything.
This is the code I'm trying to refer to:
static int its_vlpi_unmap(struct irq_data *d)
{
struct its_device *its_dev = irq_data_get_irq_chip_data(d);
u32 event = its_get_event_id(d);
if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d)) <=== this shouldn't happen?
return -EINVAL;
/* Drop the virtual mapping */
its_send_discard(its_dev, event);
/* and restore the physical one */
irqd_clr_forwarded_to_vcpu(d);
its_send_mapti(its_dev, d->hwirq, event);
lpi_update_config(d, 0xff, (lpi_prop_prio |
LPI_PROP_ENABLED |
LPI_PROP_GROUP1));
/* Potentially unmap the VM from this ITS */
its_unmap_vm(its_dev->its, its_dev->event_map.vm);
/*
* Drop the refcount and make the device available again if
* this was the last VLPI.
*/
if (!--its_dev->event_map.nr_vlpis) {
its_dev->event_map.vm = NULL;
kfree(its_dev->event_map.vlpi_maps);
}
return 0;
}
When called from kvm_vgic_v4_unset_forwarding()
if (irq->hw) {
atomic_dec(&irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count);
irq->hw = false;
ret = its_unmap_vlpi(host_irq);
}
IIUC, irq->hw is set if and only if KVM has configured the IRQ to be fowarded
directly to a vCPU. Based on this comment in its_map_vlpi():
/*
* The host will never see that interrupt firing again, so it
* is vital that we don't do any lazy masking.
*/
and this code in its_vlpi_map():
/* Drop the physical mapping */
its_send_discard(its_dev, event);
my understanding is that the associated physical IRQ will not be delivered to the
host while the IRQ is being forwarded to a vCPU.
irq->hw should only become true for MSIs (I'm crossing my fingers that SGIs aren't
in play here) if its_map_vlpi() succeeds:
ret = its_map_vlpi(virq, &map);
if (ret)
goto out_unlock_irq;
irq->hw = true;
irq->host_irq = virq;
atomic_inc(&map.vpe->vlpi_count);
and so if its_unmap_vlpi() fails in kvm_vgic_v4_unset_forwarding(), then from KVM's
perspective, the worst case scenario is that an IRQ has been left in a forwarded
state, i.e. the physical mapping hasn't been reinstalled.
KVM already WARNs if kvm_vgic_v4_unset_forwarding() fails when KVM is reacting to
a routing change (this is the WARN I want to move into arch code so that
kvm_arch_update_irqfd_routing() doesn't plumb a pointless error code up the stack):
if (irqfd->producer &&
kvm_arch_irqfd_route_changed(&old, &irqfd->irq_entry)) {
int ret = kvm_arch_update_irqfd_routing(
irqfd->kvm, irqfd->producer->irq,
irqfd->gsi, 1);
WARN_ON(ret);
}
It's only the kvm_arch_irq_bypass_del_producer() case where KVM doesn't WARN. If
that fails, then the IRQ has potentially been left in a forwarded state, despite
whatever driver "owns" the physical IRQ having removed its producer. E.g. if VFIO
detaches its irqbypass producer and gives the device back to the host, then
whatever is using the device in the host won't receive IRQs as expected.
Looking at this again, its_free_ite() also WARNs on its_unmap_vlpi() failure, so
wouldn't it make sense to have its_unmap_vlpi() WARN if irq_set_vcpu_affinity()
fails? The only possible failures are that the GIC doesn't have a v4 ITS (from
its_irq_set_vcpu_affinity()):
/* Need a v4 ITS */
if (!is_v4(its_dev->its))
return -EINVAL;
guard(raw_spinlock)(&its_dev->event_map.vlpi_lock);
/* Unmap request? */
if (!info)
return its_vlpi_unmap(d);
or that KVM has gotten out of sync with the GIC/ITS (from its_vlpi_unmap()):
if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d))
return -EINVAL;
All of those failure scenario seem like warnable offences when KVM thinks it has
configured the IRQ to be forwarded to a vCPU.
E.g.
--
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 534049c7c94b..98630dae910d 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -758,7 +758,7 @@ static void its_free_ite(struct kvm *kvm, struct its_ite *ite)
if (irq) {
scoped_guard(raw_spinlock_irqsave, &irq->irq_lock) {
if (irq->hw)
- WARN_ON(its_unmap_vlpi(ite->irq->host_irq));
+ its_unmap_vlpi(ite->irq->host_irq);
irq->hw = false;
}
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index 193946108192..911170d4a9c8 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -545,10 +545,10 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int host_irq)
if (irq->hw) {
atomic_dec(&irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count);
irq->hw = false;
- ret = its_unmap_vlpi(host_irq);
+ its_unmap_vlpi(host_irq);
}
raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
vgic_put_irq(kvm, irq);
- return ret;
+ return 0;
}
diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index 58c28895f8c4..8455b4a5fbb0 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -342,10 +342,10 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map)
return irq_set_vcpu_affinity(irq, &info);
}
-int its_unmap_vlpi(int irq)
+void its_unmap_vlpi(int irq)
{
irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY);
- return irq_set_vcpu_affinity(irq, NULL);
+ WARN_ON_ONCE(irq_set_vcpu_affinity(irq, NULL));
}
int its_prop_update_vlpi(int irq, u8 config, bool inv)
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index 7f1f11a5e4e4..0b0887099fd7 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -146,7 +146,7 @@ int its_commit_vpe(struct its_vpe *vpe);
int its_invall_vpe(struct its_vpe *vpe);
int its_map_vlpi(int irq, struct its_vlpi_map *map);
int its_get_vlpi(int irq, struct its_vlpi_map *map);
-int its_unmap_vlpi(int irq);
+void its_unmap_vlpi(int irq);
int its_prop_update_vlpi(int irq, u8 config, bool inv);
int its_prop_update_vsgi(int irq, u8 priority, bool group);
next prev parent reply other threads:[~2025-06-12 14:34 UTC|newest]
Thread overview: 113+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-11 22:45 [PATCH v3 00/62] KVM: iommu: Overhaul device posted IRQs support Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 01/62] KVM: arm64: Explicitly treat routing entry type changes as changes Sean Christopherson
2025-06-13 19:43 ` Oliver Upton
2025-06-19 12:36 ` (subset) " Marc Zyngier
2025-06-11 22:45 ` [PATCH v3 02/62] KVM: arm64: WARN if unmapping vLPI fails Sean Christopherson
2025-06-12 11:59 ` Marc Zyngier
2025-06-12 14:34 ` Sean Christopherson [this message]
2025-06-13 20:47 ` Oliver Upton
2025-06-20 17:22 ` Sean Christopherson
2025-06-20 18:00 ` David Woodhouse
2025-06-20 18:48 ` Oliver Upton
2025-06-20 19:04 ` Sean Christopherson
2025-06-20 19:27 ` Oliver Upton
2025-06-20 20:31 ` Sean Christopherson
2025-06-20 20:45 ` Oliver Upton
2025-06-11 22:45 ` [PATCH v3 03/62] KVM: Pass new routing entries and irqfd when updating IRTEs Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 04/62] KVM: SVM: Track per-vCPU IRTEs using kvm_kernel_irqfd structure Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 05/62] KVM: SVM: Delete IRTE link from previous vCPU before setting new IRTE Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 06/62] iommu/amd: KVM: SVM: Delete now-unused cached/previous GA tag fields Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 07/62] KVM: SVM: Delete IRTE link from previous vCPU irrespective of new routing Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 08/62] KVM: SVM: Drop pointless masking of default APIC base when setting V_APIC_BAR Sean Christopherson
2025-06-13 14:15 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 09/62] KVM: SVM: Drop pointless masking of kernel page pa's with AVIC HPA masks Sean Christopherson
2025-06-13 14:37 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 10/62] KVM: SVM: Add helper to deduplicate code for getting AVIC backing page Sean Christopherson
2025-06-13 14:38 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 11/62] KVM: SVM: Drop vcpu_svm's pointless avic_backing_page field Sean Christopherson
2025-06-13 14:44 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 12/62] KVM: SVM: Inhibit AVIC if ID is too big instead of rejecting vCPU creation Sean Christopherson
2025-06-17 14:25 ` Naveen N Rao
2025-06-17 16:10 ` Sean Christopherson
2025-06-18 14:33 ` Naveen N Rao
2025-06-18 20:59 ` Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 13/62] KVM: SVM: Drop redundant check in AVIC code on ID during " Sean Christopherson
2025-06-17 14:49 ` Naveen N Rao
2025-06-17 16:33 ` Sean Christopherson
2025-06-18 14:39 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 14/62] KVM: SVM: Track AVIC tables as natively sized pointers, not "struct pages" Sean Christopherson
2025-06-17 15:01 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 15/62] KVM: SVM: Drop superfluous "cache" of AVIC Physical ID entry pointer Sean Christopherson
2025-06-19 11:09 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 16/62] KVM: VMX: Move enable_ipiv knob to common x86 Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 17/62] KVM: SVM: Add enable_ipiv param, never set IsRunning if disabled Sean Christopherson
2025-06-19 11:31 ` Naveen N Rao
2025-06-19 12:01 ` Naveen N Rao
2025-06-20 14:39 ` Sean Christopherson
2025-06-23 10:45 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 18/62] KVM: SVM: Disable (x2)AVIC IPI virtualization if CPU has erratum #1235 Sean Christopherson
2025-06-23 14:05 ` Naveen N Rao
2025-06-23 15:30 ` Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 19/62] KVM: VMX: Suppress PI notifications whenever the vCPU is put Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 20/62] KVM: SVM: Add a comment to explain why avic_vcpu_blocking() ignores IRQ blocking Sean Christopherson
2025-06-23 15:54 ` Naveen N Rao
2025-06-23 16:18 ` Sean Christopherson
2025-06-25 15:28 ` Naveen N Rao
2025-06-11 22:45 ` [PATCH v3 21/62] iommu/amd: KVM: SVM: Use pi_desc_addr to derive ga_root_ptr Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 22/62] iommu/amd: KVM: SVM: Pass NULL @vcpu_info to indicate "not guest mode" Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 23/62] KVM: SVM: Stop walking list of routing table entries when updating IRTE Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 24/62] KVM: VMX: " Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 25/62] KVM: SVM: Extract SVM specific code out of get_pi_vcpu_info() Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 26/62] KVM: x86: Move IRQ routing/delivery APIs from x86.c => irq.c Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 27/62] KVM: x86: Nullify irqfd->producer after updating IRTEs Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 28/62] KVM: x86: Dedup AVIC vs. PI code for identifying target vCPU Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 29/62] KVM: x86: Move posted interrupt tracepoint to common code Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 30/62] KVM: SVM: Clean up return handling in avic_pi_update_irte() Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 31/62] iommu: KVM: Split "struct vcpu_data" into separate AMD vs. Intel structs Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 32/62] KVM: Don't WARN if updating IRQ bypass route fails Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 33/62] KVM: Fold kvm_arch_irqfd_route_changed() into kvm_arch_update_irqfd_routing() Sean Christopherson
2025-06-13 20:50 ` Oliver Upton
2025-06-11 22:45 ` [PATCH v3 34/62] KVM: x86: Track irq_bypass_vcpu in common x86 code Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 35/62] KVM: x86: Skip IOMMU IRTE updates if there's no old or new vCPU being targeted Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 36/62] KVM: x86: Don't update IRTE entries when old and new routes were !MSI Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 37/62] KVM: SVM: Revert IRTE to legacy mode if IOMMU doesn't provide IR metadata Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 38/62] KVM: SVM: Take and hold ir_list_lock across IRTE updates in IOMMU Sean Christopherson
2025-06-17 15:42 ` Naveen N Rao
2025-12-22 9:16 ` Ankit Soni
2025-12-22 14:09 ` possible deadlock due to irq_set_thread_affinity() calling into the scheduler (was Re: [PATCH v3 38/62] KVM: SVM: Take and hold ir_list_lock across IRTE updates in IOMMU) Paolo Bonzini
2025-12-22 19:34 ` Sean Christopherson
2025-12-22 21:15 ` Paolo Bonzini
2025-12-22 22:10 ` Sean Christopherson
2025-12-23 8:59 ` Ankit Soni
2026-01-08 21:28 ` Thomas Gleixner
2026-01-08 21:53 ` Thomas Gleixner
2026-01-21 15:53 ` Paolo Bonzini
2026-01-21 18:13 ` Paolo Bonzini
2026-01-22 10:19 ` Marc Zyngier
2026-01-22 18:47 ` Thomas Gleixner
2026-01-24 7:49 ` Paolo Bonzini
2025-06-11 22:45 ` [PATCH v3 39/62] iommu/amd: Document which IRTE fields amd_iommu_update_ga() can modify Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 40/62] iommu/amd: KVM: SVM: Infer IsRun from validity of pCPU destination Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 41/62] iommu/amd: Factor out helper for manipulating IRTE GA/CPU info Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 42/62] iommu/amd: KVM: SVM: Set pCPU info in IRTE when setting vCPU affinity Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 43/62] iommu/amd: KVM: SVM: Add IRTE metadata to affined vCPU's list if AVIC is inhibited Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 44/62] KVM: SVM: Don't check for assigned device(s) when updating affinity Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 45/62] KVM: SVM: Don't check for assigned device(s) when activating AVIC Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 46/62] KVM: SVM: WARN if (de)activating guest mode in IOMMU fails Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 47/62] KVM: SVM: Process all IRTEs on affinity change even if one update fails Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 48/62] KVM: SVM: WARN if updating IRTE GA fields in IOMMU fails Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 49/62] KVM: x86: Drop superfluous "has assigned device" check in kvm_pi_update_irte() Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 50/62] KVM: x86: WARN if IRQ bypass isn't supported " Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 51/62] KVM: x86: WARN if IRQ bypass routing is updated without in-kernel local APIC Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 52/62] KVM: SVM: WARN if ir_list is non-empty at vCPU free Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 53/62] KVM: x86: Decouple device assignment from IRQ bypass Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 54/62] KVM: VMX: WARN if VT-d Posted IRQs aren't possible when starting " Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 55/62] KVM: SVM: Use vcpu_idx, not vcpu_id, for GA log tag/metadata Sean Christopherson
2025-06-11 22:45 ` [PATCH v3 56/62] iommu/amd: WARN if KVM calls GA IRTE helpers without virtual APIC support Sean Christopherson
2025-06-11 22:46 ` [PATCH v3 57/62] KVM: SVM: Fold avic_set_pi_irte_mode() into its sole caller Sean Christopherson
2025-06-11 22:46 ` [PATCH v3 58/62] KVM: SVM: Don't check vCPU's blocking status when toggling AVIC on/off Sean Christopherson
2025-06-11 22:46 ` [PATCH v3 59/62] KVM: SVM: Consolidate IRTE update " Sean Christopherson
2025-06-11 22:46 ` [PATCH v3 60/62] iommu/amd: KVM: SVM: Allow KVM to control need for GA log interrupts Sean Christopherson
2025-06-11 22:46 ` [PATCH v3 61/62] KVM: SVM: Generate GA log IRQs only if the associated vCPUs is blocking Sean Christopherson
2025-06-11 22:46 ` [PATCH v3 62/62] KVM: x86: Rename kvm_set_msi_irq() => kvm_msi_to_lapic_irq() Sean Christopherson
2025-06-24 19:38 ` [PATCH v3 00/62] KVM: iommu: Overhaul device posted IRQs support Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aErlezuoFJ8u0ue-@google.com \
--to=seanjc@google.com \
--cc=baolu.lu@linux.intel.com \
--cc=dmatlack@google.com \
--cc=dwmw2@infradead.org \
--cc=francescolavra.fl@gmail.com \
--cc=iommu@lists.linux.dev \
--cc=joao.m.martins@oracle.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=mlevitsk@redhat.com \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=sarunkod@amd.com \
--cc=vasant.hegde@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox