[PATCH 1/2] iommu/riscv: Map IMSIC addresses for paging domains
Andrew Jones
andrew.jones at oss.qualcomm.com
Tue May 12 09:22:46 PDT 2026
On Tue, May 12, 2026 at 10:38:54AM -0300, Jason Gunthorpe wrote:
> On Fri, May 08, 2026 at 04:23:38PM -0500, Andrew Jones wrote:
> > +static void riscv_iommu_get_resv_regions(struct device *dev, struct list_head *head)
> > +{
> > + const struct imsic_global_config *imsic_global;
> > + unsigned int cpu;
> > +
> > + if (!imsic_enabled())
> > + return;
> > +
> > + imsic_global = imsic_get_global_config();
> > +
> > + for_each_possible_cpu(cpu) {
> > + const struct imsic_local_config *local;
> > + struct iommu_resv_region *reg;
> > +
> > + local = per_cpu_ptr(imsic_global->local, cpu);
> > + if (!local->msi_va)
> > + continue;
> > +
> > + /*
> > + * The device always writes to the host physical IMSIC address, so install
> > + * identity mappings directly. Use IOMMU_RESV_DIRECT_RELAXABLE instead of
> > + * IOMMU_RESV_DIRECT since these 1:1 mappings are not required for assigned
> > + * devices.
>
> Oh? Why not?
Hi Jason,
I should change the comment above to be stronger. 'not required' sounds
like a choice is being made, but guest devices must not have mappings to
host IMSICs - that would break their isolation.
RISC-V AIA has the concept of guest interrupt files. Assigned devices must
write the addresses of those interrupt files to deliver MSIs to guest
IMSICs (virtual IMSICs). Also, the VMM can map the virtual IMSICs where it
likes, which will not necessarily be the same addresses the host IMSICs
use. We need the irqbypass series I'm working on for guests, not these
direct mappings.
Also, I actually discovered IOMMU_RESV_DIRECT_RELAXABLE after first trying
IOMMU_RESV_DIRECT which resulted in "Firmware has requested this device
have a 1:1 IOMMU mapping, rejecting..." failures when running the vfio
kselftests.
>
> > + reg = iommu_alloc_resv_region(local->msi_pa, IMSIC_MMIO_PAGE_SZ,
> > + IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO,
> > + IOMMU_RESV_DIRECT_RELAXABLE, GFP_KERNEL);
> > + if (reg)
> > + list_add_tail(®->list, head);
>
> This seems like quite a hack, the ARM was seems much better, the
> interrupt controller should be using the iommu_dma_prepare_msi() path
> to obtain an appropriately translated MSI address for the aperture.
The difference between ARM and RISC-V is that on RISC-V each CPU has an
IMSIC and the device will target any one of them, depending on its current
affinity (i.e. the MSI target changes with irq-set-affinity). ARM has a
single doorbell address which has a single IOVA->PA mapping created for
it that never changes. The ITS manages everything, including affinity
changes. Even when I get an IR irqdomain posted that implements
irq-set-affinity to help further isolate devices on the host, we'll still
want get_resv to pre-create these direct mappings since we can't
create/alloc them at irq-set-affinity time which runs in atomic context.
Thanks,
drew
More information about the linux-riscv
mailing list