Re: [RFC PATCH 17/18] target/riscv: Pass first/last to get_physical_address_pmp
Alistair <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv |
|---|---|
| Message-ID | <[email protected]> |
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) {