Unverified Commit ddf78132 authored by Bin Meng's avatar Bin Meng Committed by Palmer Dabbelt
Browse files

riscv: rv32: Root page table address can be larger than 32-bit



For RV32, the root page table's PPN has 22 bits hence its address
bits could be larger than the maximum bits that target_ulong is
able to represent. Use hwaddr instead.

Signed-off-by: default avatarBin Meng <bmeng.cn@gmail.com>
Reviewed-by: default avatarAlistair Francis <alistair.francis@wdc.com>
Signed-off-by: default avatarPalmer Dabbelt <palmer@sifive.com>
parent 7f8dcfeb
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -186,12 +186,12 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,

    *prot = 0;

    target_ulong base;
    hwaddr base;
    int levels, ptidxbits, ptesize, vm, sum;
    int mxr = get_field(env->mstatus, MSTATUS_MXR);

    if (env->priv_ver >= PRIV_VERSION_1_10_0) {
        base = get_field(env->satp, SATP_PPN) << PGSHIFT;
        base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
        sum = get_field(env->mstatus, MSTATUS_SUM);
        vm = get_field(env->satp, SATP_MODE);
        switch (vm) {
@@ -211,7 +211,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
          g_assert_not_reached();
        }
    } else {
        base = env->sptbr << PGSHIFT;
        base = (hwaddr)(env->sptbr) << PGSHIFT;
        sum = !get_field(env->mstatus, MSTATUS_PUM);
        vm = get_field(env->mstatus, MSTATUS_VM);
        switch (vm) {
@@ -249,7 +249,7 @@ restart:
                           ((1 << ptidxbits) - 1);

        /* check that physical address of PTE is legal */
        target_ulong pte_addr = base + idx * ptesize;
        hwaddr pte_addr = base + idx * ptesize;

        if (riscv_feature(env, RISCV_FEATURE_PMP) &&
            !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
@@ -261,7 +261,7 @@ restart:
#elif defined(TARGET_RISCV64)
        target_ulong pte = ldq_phys(cs->as, pte_addr);
#endif
        target_ulong ppn = pte >> PTE_PPN_SHIFT;
        hwaddr ppn = pte >> PTE_PPN_SHIFT;

        if (!(pte & PTE_V)) {
            /* Invalid PTE */