Message ID | 20230325105429.1142530-9-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/riscv: MSTATUS_SUM + cleanups | expand |
On Sat, Mar 25, 2023 at 9:52 PM Richard Henderson <richard.henderson@linaro.org> wrote: > > At least RISC-V has the need to be able to perform a read > using execute permissions, outside of translation. > Add helpers to facilitate this. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Acked-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > include/exec/cpu_ldst.h | 9 +++++++ > accel/tcg/cputlb.c | 48 ++++++++++++++++++++++++++++++++++ > accel/tcg/user-exec.c | 58 +++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 115 insertions(+) > > diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h > index 09b55cc0ee..c141f0394f 100644 > --- a/include/exec/cpu_ldst.h > +++ b/include/exec/cpu_ldst.h > @@ -445,6 +445,15 @@ static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx, > # define cpu_stq_mmu cpu_stq_le_mmu > #endif > > +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra); > +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra); > +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra); > +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra); > + > uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr); > uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr); > uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr); > diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c > index e984a98dc4..e62c8f3c3f 100644 > --- a/accel/tcg/cputlb.c > +++ b/accel/tcg/cputlb.c > @@ -2768,3 +2768,51 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr) > MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true)); > return full_ldq_code(env, addr, oi, 0); > } > + > +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t retaddr) > +{ > + return full_ldub_code(env, addr, oi, retaddr); > +} > + > +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t retaddr) > +{ > + MemOp mop = get_memop(oi); > + int idx = get_mmuidx(oi); > + uint16_t ret; > + > + ret = full_lduw_code(env, addr, make_memop_idx(MO_TEUW, idx), retaddr); > + if ((mop & MO_BSWAP) != MO_TE) { > + ret = bswap16(ret); > + } > + return ret; > +} > + > +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t retaddr) > +{ > + MemOp mop = get_memop(oi); > + int idx = get_mmuidx(oi); > + uint32_t ret; > + > + ret = full_ldl_code(env, addr, make_memop_idx(MO_TEUL, idx), retaddr); > + if ((mop & MO_BSWAP) != MO_TE) { > + ret = bswap32(ret); > + } > + return ret; > +} > + > +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t retaddr) > +{ > + MemOp mop = get_memop(oi); > + int idx = get_mmuidx(oi); > + uint64_t ret; > + > + ret = full_ldq_code(env, addr, make_memop_idx(MO_TEUQ, idx), retaddr); > + if ((mop & MO_BSWAP) != MO_TE) { > + ret = bswap64(ret); > + } > + return ret; > +} > diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c > index 7b37fd229e..44e0ea55ba 100644 > --- a/accel/tcg/user-exec.c > +++ b/accel/tcg/user-exec.c > @@ -1222,6 +1222,64 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr ptr) > return ret; > } > > +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra) > +{ > + void *haddr; > + uint8_t ret; > + > + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); > + ret = ldub_p(haddr); > + clear_helper_retaddr(); > + return ret; > +} > + > +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra) > +{ > + void *haddr; > + uint16_t ret; > + > + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); > + ret = lduw_p(haddr); > + clear_helper_retaddr(); > + if (get_memop(oi) & MO_BSWAP) { > + ret = bswap16(ret); > + } > + return ret; > +} > + > +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra) > +{ > + void *haddr; > + uint32_t ret; > + > + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); > + ret = ldl_p(haddr); > + clear_helper_retaddr(); > + if (get_memop(oi) & MO_BSWAP) { > + ret = bswap32(ret); > + } > + return ret; > +} > + > +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, > + MemOpIdx oi, uintptr_t ra) > +{ > + void *haddr; > + uint64_t ret; > + > + validate_memop(oi, MO_BEUQ); > + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD); > + ret = ldq_p(haddr); > + clear_helper_retaddr(); > + if (get_memop(oi) & MO_BSWAP) { > + ret = bswap64(ret); > + } > + return ret; > +} > + > #include "ldst_common.c.inc" > > /* > -- > 2.34.1 > >
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h index 09b55cc0ee..c141f0394f 100644 --- a/include/exec/cpu_ldst.h +++ b/include/exec/cpu_ldst.h @@ -445,6 +445,15 @@ static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx, # define cpu_stq_mmu cpu_stq_le_mmu #endif +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra); +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra); +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra); +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra); + uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr); uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr); uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr); diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index e984a98dc4..e62c8f3c3f 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -2768,3 +2768,51 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr) MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true)); return full_ldq_code(env, addr, oi, 0); } + +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + return full_ldub_code(env, addr, oi, retaddr); +} + +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + MemOp mop = get_memop(oi); + int idx = get_mmuidx(oi); + uint16_t ret; + + ret = full_lduw_code(env, addr, make_memop_idx(MO_TEUW, idx), retaddr); + if ((mop & MO_BSWAP) != MO_TE) { + ret = bswap16(ret); + } + return ret; +} + +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + MemOp mop = get_memop(oi); + int idx = get_mmuidx(oi); + uint32_t ret; + + ret = full_ldl_code(env, addr, make_memop_idx(MO_TEUL, idx), retaddr); + if ((mop & MO_BSWAP) != MO_TE) { + ret = bswap32(ret); + } + return ret; +} + +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + MemOp mop = get_memop(oi); + int idx = get_mmuidx(oi); + uint64_t ret; + + ret = full_ldq_code(env, addr, make_memop_idx(MO_TEUQ, idx), retaddr); + if ((mop & MO_BSWAP) != MO_TE) { + ret = bswap64(ret); + } + return ret; +} diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 7b37fd229e..44e0ea55ba 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -1222,6 +1222,64 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr ptr) return ret; } +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint8_t ret; + + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); + ret = ldub_p(haddr); + clear_helper_retaddr(); + return ret; +} + +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint16_t ret; + + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); + ret = lduw_p(haddr); + clear_helper_retaddr(); + if (get_memop(oi) & MO_BSWAP) { + ret = bswap16(ret); + } + return ret; +} + +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint32_t ret; + + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); + ret = ldl_p(haddr); + clear_helper_retaddr(); + if (get_memop(oi) & MO_BSWAP) { + ret = bswap32(ret); + } + return ret; +} + +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint64_t ret; + + validate_memop(oi, MO_BEUQ); + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD); + ret = ldq_p(haddr); + clear_helper_retaddr(); + if (get_memop(oi) & MO_BSWAP) { + ret = bswap64(ret); + } + return ret; +} + #include "ldst_common.c.inc" /*
At least RISC-V has the need to be able to perform a read using execute permissions, outside of translation. Add helpers to facilitate this. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- include/exec/cpu_ldst.h | 9 +++++++ accel/tcg/cputlb.c | 48 ++++++++++++++++++++++++++++++++++ accel/tcg/user-exec.c | 58 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+)