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
> 
> 

Reply via email to