On Sat, 2026-08-15 at 13:37 -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <[email protected]>

Reviewed-by: Alistair Francis <[email protected]>

Alistair

> ---
>  target/riscv/tcg/cpu_helper.c | 48 +++++++++++++++++++--------------
> --
>  1 file changed, 26 insertions(+), 22 deletions(-)
> 
> diff --git a/target/riscv/tcg/cpu_helper.c
> b/target/riscv/tcg/cpu_helper.c
> index 3318e82ea7..fb1250a4b8 100644
> --- a/target/riscv/tcg/cpu_helper.c
> +++ b/target/riscv/tcg/cpu_helper.c
> @@ -899,12 +899,13 @@ void riscv_cpu_set_mode(CPURISCVState *env,
> privilege_mode_t newpriv,
>   *
>   * @env: CPURISCVState
>   * @prot: The returned protection attributes
> - * @addr: The physical address to be checked permission
> + * @first, @last: The physical address range to be permission
> checked
>   * @access_type: The type of MMU access
>   * @mode: Indicates current privilege level.
>   */
> -static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> hwaddr addr,
> -                                    int size, MMUAccessType
> access_type,
> +static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> +                                    hwaddr first, hwaddr last,
> +                                    MMUAccessType access_type,
>                                      privilege_mode_t mode)
>  {
>      pmp_priv_t pmp_priv;
> @@ -915,8 +916,8 @@ static int get_physical_address_pmp(CPURISCVState
> *env, int *prot, hwaddr addr,
>          return TRANSLATE_SUCCESS;
>      }
>  
> -    pmp_has_privs = pmp_hart_has_privs(env, addr, size, 1 <<
> access_type,
> -                                       &pmp_priv, mode);
> +    pmp_has_privs = pmp_hart_has_privs(env, first, last - first + 1,
> +                                       1 << access_type, &pmp_priv,
> mode);
>      if (!pmp_has_privs) {
>          *prot = 0;
>          return TRANSLATE_PMP_FAIL;
> @@ -1142,6 +1143,8 @@ static int get_physical_address(CPURISCVState
> *env, hwaddr *physical,
>      base = base_root;
>      for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
>          target_ulong idx;
> +        int pmp_prot, pmp_ret;
> +
>          if (i == 0) {
>              idx = (addr >> (PGSHIFT + ptshift)) &
>                             ((1 << (ptidxbits + widened)) - 1);
> @@ -1174,10 +1177,9 @@ static int get_physical_address(CPURISCVState
> *env, hwaddr *physical,
>              pte_addr = base + idx * ptesize;
>          }
>  
> -        int pmp_prot;
> -        int pmp_ret = get_physical_address_pmp(env, &pmp_prot,
> pte_addr,
> -                                               sxlen_bytes,
> -                                               MMU_DATA_LOAD,
> PRV_S);
> +        pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr,
> +                                           pte_addr + sxlen_bytes -
> 1,
> +                                           MMU_DATA_LOAD, PRV_S);
>          if (pmp_ret != TRANSLATE_SUCCESS) {
>              return TRANSLATE_PMP_FAIL;
>          }
> @@ -1425,7 +1427,8 @@ static int get_physical_address(CPURISCVState
> *env, hwaddr *physical,
>          }
>  
>          pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr,
> -                                           sxlen_bytes,
> MMU_DATA_STORE, PRV_S);
> +                                           pte_addr + sxlen_bytes -
> 1,
> +                                           MMU_DATA_STORE, PRV_S);
>          if (pmp_ret != TRANSLATE_SUCCESS) {
>              return TRANSLATE_PMP_FAIL;
>          }
> @@ -1655,8 +1658,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address, vaddr first, vaddr last,
>  {
>      RISCVCPU *cpu = RISCV_CPU(cs);
>      CPURISCVState *env = &cpu->env;
> -    int size = last - address + 1;
> -    vaddr im_address;
>      hwaddr pa = 0;
>      int prot, prot2, prot_pmp;
>      bool pmp_pma_violation = false;
> @@ -1676,7 +1677,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address, vaddr first, vaddr last,
>      pmu_tlb_fill_incr_ctr(cpu, access_type);
>      if (two_stage_lookup) {
>          /* Two stage lookup */
> -        ret = get_physical_address(env, &pa, &prot, address,
> +        ret = get_physical_address(env, &pa, &prot, first,
>                                     &env->guest_phys_fault_addr,
> access_type,
>                                     mmu_idx, true, true, false,
> probe);
>          /*
> @@ -1692,11 +1693,11 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address, vaddr first, vaddr last,
>          qemu_log_mask(CPU_LOG_MMU,
>                        "%s 1st-stage address=%" VADDR_PRIx " ret %d
> physical "
>                        HWADDR_FMT_plx " prot %d\n",
> -                      __func__, address, ret, pa, prot);
> +                      __func__, first, ret, pa, prot);
>  
>          if (ret == TRANSLATE_SUCCESS) {
>              /* Second stage lookup */
> -            im_address = pa;
> +            vaddr im_address = pa;
>  
>              ret = get_physical_address(env, &pa, &prot2, im_address,
> NULL,
>                                         access_type, MMUIdx_U, false,
> true,
> @@ -1711,8 +1712,9 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address, vaddr first, vaddr last,
>              prot &= prot2;
>  
>              if (ret == TRANSLATE_SUCCESS) {
> -                ret = get_physical_address_pmp(env, &prot_pmp, pa,
> -                                               size, access_type,
> mode);
> +                ret = get_physical_address_pmp(env, &prot_pmp,
> +                                               pa, pa + (last -
> first),
> +                                               access_type, mode);
>                  tlb_size = pmp_get_tlb_size(env, pa);
>  
>                  qemu_log_mask(CPU_LOG_MMU,
> @@ -1736,18 +1738,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address, vaddr first, vaddr last,
>          }
>      } else {
>          /* Single stage lookup */
> -        ret = get_physical_address(env, &pa, &prot, address, NULL,
> +        ret = get_physical_address(env, &pa, &prot, first, NULL,
>                                     access_type, mmu_idx, true,
> false, false,
>                                     probe);
>  
>          qemu_log_mask(CPU_LOG_MMU,
>                        "%s address=%" VADDR_PRIx " ret %d physical "
>                        HWADDR_FMT_plx " prot %d\n",
> -                      __func__, address, ret, pa, prot);
> +                      __func__, first, ret, pa, prot);
>  
>          if (ret == TRANSLATE_SUCCESS) {
> -            ret = get_physical_address_pmp(env, &prot_pmp, pa,
> -                                           size, access_type, mode);
> +            ret = get_physical_address_pmp(env, &prot_pmp,
> +                                           pa, pa + (last - first),
> +                                           access_type, mode);
>              tlb_size = pmp_get_tlb_size(env, pa);
>  
>              qemu_log_mask(CPU_LOG_MMU,
> @@ -1764,7 +1767,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address, vaddr first, vaddr last,
>      }
>  
>      if (ret == TRANSLATE_SUCCESS) {
> -        tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size
> - 1),
> +        tlb_set_page(cs, address & ~(tlb_size - 1),
> +                     (pa + (address - first)) & ~(tlb_size - 1),
>                       prot, mmu_idx, tlb_size);
>          return true;
>      } else if (probe) {

Reply via email to