Hi Eric,
> -----Original Message-----
> From: Eric Auger <[email protected]>
> Sent: 04 December 2025 16:39
> To: Shameer Kolothum <[email protected]>; qemu-
> [email protected]; [email protected]
> Cc: [email protected]; Jason Gunthorpe <[email protected]>; Nicolin
> Chen <[email protected]>; [email protected]; [email protected];
> Nathan Chen <[email protected]>; Matt Ochs <[email protected]>;
> [email protected]; [email protected];
> [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> Krishnakant Jaju <[email protected]>; Michael S . Tsirkin <[email protected]>
> Subject: Re: [PATCH v6 16/33] hw/pci/pci: Introduce a callback to retrieve the
> MSI doorbell GPA directly
>
> External email: Use caution opening links or attachments
...
> > --- a/target/arm/kvm.c
> > +++ b/target/arm/kvm.c
> > @@ -1620,26 +1620,42 @@ int kvm_arch_fixup_msi_route(struct
> kvm_irq_routing_entry *route,
> > return 0;
> > }
> >
> > + /*
> > + * We do have an IOMMU address space, but for some vIOMMU
> implementations
> > + * (e.g. accelerated SMMUv3) the translation tables are programmed into
> > + * the physical SMMUv3 in the host (nested S1=guest, S2=host). QEMU
> cannot
> > + * walk these tables in a safe way, so in that case we obtain the MSI
> > + * doorbell GPA directly from the vIOMMU backend and ignore the
> gIOVA
> > + * @address.
> > + */
> > + if (pci_device_iommu_msi_direct_gpa(dev, &doorbell_gpa)) {
> > + goto set_doorbell;
> > + }
> > +
> > /* MSI doorbell address is translated by an IOMMU */
> >
> > - RCU_READ_LOCK_GUARD();
> > + rcu_read_lock();
> what is the rationale behind the RCU changes?
>
Otherwise, it will crash if this fn returns via the goto set_doorbell path
with,
include/qemu/rcu.h:101: rcu_read_unlock: Assertion `p_rcu_reader->depth != 0'
failed
goto set_doorbell path skips over the scope where RCU_READ_LOCK_GUARD()
is active. When the function later reaches rcu_read_unlock() implicitly via
destructor, the guard was never entered, so we hit above.
An alternative would be to wrap the translation logic in its own block, like
if (pci_device_iommu_msi_direct_gpa(dev, &doorbell_gpa)) {
goto set_doorbell;
}
{
RCU_READ_LOCK_GUARD();
/* MSI translation logic */
}
set_doorbell:
route->u.msi.address_lo = doorbell_gpa;
route->u.msi.address_hi = doorbell_gpa >> 32;
return 0;
Or could do:
if (!pci_device_iommu_msi_direct_gpa(dev, &doorbell_gpa)) {
RCU_READ_LOCK_GUARD();
/* translation logic */
}
route->u.msi.address_lo = doorbell_gpa;
route->u.msi.address_hi = doorbell_gpa >> 32;
return 0;
Both approaches work, but I find the explicit lock/unlock variant easier
to follow. Please let me know if there is a better way.
Thanks,
Shameer