Hi Jim, On Mon, Feb 02, 2026 at 03:53:58PM +0800, Jim Shu wrote: > Instead of IOMMU_NONE, address_space_translate_for_iotlb() now can pass > the correct iommu_flags to the IOMMU translate function from the > access_type. > > Since RISC-V wgChecker [1] could permit access in RO or WO permission > only, the IOMMUMemoryRegion could return different section for > read and write access. To support this kind of IOMMUMemoryRegion > in the path of CPU access, we should pass correct iommu_flags here. > > [1] RISC-V WG: > https://patchew.org/QEMU/[email protected]/ > > Signed-off-by: Jim Shu <[email protected]> > --- > accel/tcg/cputlb.c | 3 ++- > include/accel/tcg/iommu.h | 3 ++- > system/physmem.c | 16 +++++++++++----- > 3 files changed, 15 insertions(+), 7 deletions(-) > > diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c > index 2a0f4cfff62..404a8607b9b 100644 > --- a/accel/tcg/cputlb.c > +++ b/accel/tcg/cputlb.c > @@ -1050,7 +1050,8 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, > prot = full->prot; > asidx = cpu_asidx_from_attrs(cpu, full->attrs); > section = address_space_translate_for_iotlb(cpu, asidx, paddr_page, > - &xlat, &sz, full->attrs, > &prot); > + &xlat, &sz, full->attrs, > &prot, > + access_type); > assert(sz >= TARGET_PAGE_SIZE); > > tlb_debug("vaddr=%016" VADDR_PRIx " paddr=0x" HWADDR_FMT_plx > diff --git a/include/accel/tcg/iommu.h b/include/accel/tcg/iommu.h > index 547f8ea0ef0..2a79f859834 100644 > --- a/include/accel/tcg/iommu.h > +++ b/include/accel/tcg/iommu.h > @@ -20,7 +20,8 @@ MemoryRegionSection > *address_space_translate_for_iotlb(CPUState *cpu, > hwaddr *xlat, > hwaddr *plen, > MemTxAttrs attrs, > - int *prot); > + int *prot, > + MMUAccessType > access_type); > > #endif > > diff --git a/system/physmem.c b/system/physmem.c > index 2fb0c25c93b..337137489de 100644 > --- a/system/physmem.c > +++ b/system/physmem.c > @@ -683,12 +683,14 @@ void tcg_iommu_init_notifier_list(CPUState *cpu) > MemoryRegionSection * > address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr, > hwaddr *xlat, hwaddr *plen, > - MemTxAttrs attrs, int *prot) > + MemTxAttrs attrs, int *prot, > + MMUAccessType access_type) > { > MemoryRegionSection *section; > IOMMUMemoryRegion *iommu_mr; > IOMMUMemoryRegionClass *imrc; > IOMMUTLBEntry iotlb; > + IOMMUAccessFlags iommu_flags; > int iommu_idx; > hwaddr addr = orig_addr; > AddressSpaceDispatch *d = > address_space_to_dispatch(cpu->cpu_ases[asidx].as); > @@ -705,10 +707,14 @@ address_space_translate_for_iotlb(CPUState *cpu, int > asidx, hwaddr orig_addr, > > iommu_idx = imrc->attrs_to_index(iommu_mr, attrs); > tcg_register_iommu_notifier(cpu, iommu_mr, iommu_idx); > - /* We need all the permissions, so pass IOMMU_NONE so the IOMMU > - * doesn't short-cut its translation table walk. > - */ > - iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, iommu_idx); > + > + if (access_type == MMU_DATA_STORE) { > + iommu_flags = IOMMU_WO; > + } else { > + iommu_flags = IOMMU_RO; > + } This maps both MMU_INST_FETCH and MMU_DATA_LOAD to IOMMU_RO. Is this intentional? Some IOMMU implementations might want to distinguish between instruction fetch and data read.
Or is the current mapping sufficient for your use case (RISC-V wgChecker)? Thanks, Chao > + > + iotlb = imrc->translate(iommu_mr, addr, iommu_flags, iommu_idx); > addr = ((iotlb.translated_addr & ~iotlb.addr_mask) > | (addr & iotlb.addr_mask)); > /* Update the caller's prot bits to remove permissions the IOMMU > -- > 2.43.0 > >
