* [PATCH 0/8] target/arm: Misc cleanups surrounding TBI @ 2020-02-25 3:12 Richard Henderson 2020-02-25 3:12 ` [PATCH 1/8] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson ` (2 more replies) 0 siblings, 3 replies; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:12 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm We have a bug at present wherein we do not supply the memory tag to the memory system, so that on fault FAR_ELx does not contain the correct value. For system mode, we already handle ignoring TBI in get_phys_addr_lpae, as long as we don't actually drop the tag during translation. For user mode, we don't have that option, so for now we must simply accept that we'll get the wrong value in the siginfo_t. In the process of looking at all that I found: * Exception return was not applying TBI in copying ELR_ELx to PC, - Extracting the current mmu_idx can be improved, - Replicating the TBI bits can allow bit 55 to be used unconditionally, eliminating a test. * DC_ZVA was not handling TBI (now only for user-mode) - The helper need not have been in op_helper.c, - The helper could have better tcg markup. * TBI still applies when translation is disabled, and we weren't raising AddressSpace for bad physical addresses. * SVE hasn't been updated to handle TBI. I have done nothing about this for now. For the moment, system mode will work properly, while user-only will only work without tags. I'll have to touch the same places to add MTE support, so it'll get done shortly. r~ Richard Henderson (8): target/arm: Replicate TBI/TBID bits for single range regimes target/arm: Optimize cpu_mmu_index target/arm: Apply TBI to ESR_ELx in helper_exception_return target/arm: Move helper_dc_zva to helper-a64.c target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva target/arm: Clean address for DC ZVA target/arm: Check addresses for disabled regimes target/arm: Disable clean_data_tbi for system mode target/arm/cpu.h | 23 ++++---- target/arm/helper-a64.h | 1 + target/arm/helper.h | 1 - target/arm/helper-a64.c | 114 ++++++++++++++++++++++++++++++++++++- target/arm/helper.c | 44 +++++++++++--- target/arm/op_helper.c | 93 ------------------------------ target/arm/translate-a64.c | 13 ++++- 7 files changed, 175 insertions(+), 114 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/8] target/arm: Replicate TBI/TBID bits for single range regimes 2020-02-25 3:12 [PATCH 0/8] target/arm: Misc cleanups surrounding TBI Richard Henderson @ 2020-02-25 3:12 ` Richard Henderson 2020-03-02 12:00 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson 2020-03-02 11:56 ` [PATCH 0/8] target/arm: Misc cleanups surrounding TBI Peter Maydell 2 siblings, 1 reply; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:12 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm Replicate the single TBI bit from TCR_EL2 and TCR_EL3 so that we can unconditionally use pointer bit 55 to index into our composite TBI1:TBI0 field. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/helper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 79db169e04..c1dae83700 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -10297,7 +10297,8 @@ static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx) } else if (mmu_idx == ARMMMUIdx_Stage2) { return 0; /* VTCR_EL2 */ } else { - return extract32(tcr, 20, 1); + /* Replicate the single TBI bit so we always have 2 bits. */ + return extract32(tcr, 20, 1) * 3; } } @@ -10308,7 +10309,8 @@ static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx) } else if (mmu_idx == ARMMMUIdx_Stage2) { return 0; /* VTCR_EL2 */ } else { - return extract32(tcr, 29, 1); + /* Replicate the single TBID bit so we always have 2 bits. */ + return extract32(tcr, 29, 1) * 3; } } -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 1/8] target/arm: Replicate TBI/TBID bits for single range regimes 2020-02-25 3:12 ` [PATCH 1/8] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson @ 2020-03-02 12:00 ` Peter Maydell 0 siblings, 0 replies; 16+ messages in thread From: Peter Maydell @ 2020-03-02 12:00 UTC (permalink / raw) To: Richard Henderson; +Cc: qemu-arm, QEMU Developers On Tue, 25 Feb 2020 at 03:12, Richard Henderson <richard.henderson@linaro.org> wrote: > > Replicate the single TBI bit from TCR_EL2 and TCR_EL3 so that > we can unconditionally use pointer bit 55 to index into our > composite TBI1:TBI0 field. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/helper.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/8] target/arm: Optimize cpu_mmu_index 2020-02-25 3:12 [PATCH 0/8] target/arm: Misc cleanups surrounding TBI Richard Henderson 2020-02-25 3:12 ` [PATCH 1/8] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson @ 2020-02-25 3:14 ` Richard Henderson 2020-02-25 3:14 ` [PATCH 3/8] target/arm: Apply TBI to ESR_ELx in helper_exception_return Richard Henderson ` (6 more replies) 2020-03-02 11:56 ` [PATCH 0/8] target/arm: Misc cleanups surrounding TBI Peter Maydell 2 siblings, 7 replies; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:14 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm We now cache the core mmu_idx in env->hflags. Rather than recompute from scratch, extract the field. All of the uses of cpu_mmu_index within target/arm are within helpers where env->hflags is stable. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/cpu.h | 23 +++++++++++++---------- target/arm/helper.c | 5 ----- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 65171cb30e..0e53cc255e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2939,16 +2939,6 @@ typedef enum ARMMMUIdxBit { #define MMU_USER_IDX 0 -/** - * cpu_mmu_index: - * @env: The cpu environment - * @ifetch: True for code access, false for data access. - * - * Return the core mmu index for the current translation regime. - * This function is used by generic TCG code paths. - */ -int cpu_mmu_index(CPUARMState *env, bool ifetch); - /* Indexes used when registering address spaces with cpu_address_space_init */ typedef enum ARMASIdx { ARMASIdx_NS = 0, @@ -3228,6 +3218,19 @@ FIELD(TBFLAG_A64, BTYPE, 10, 2) /* Not cached. */ FIELD(TBFLAG_A64, TBID, 12, 2) FIELD(TBFLAG_A64, UNPRIV, 14, 1) +/** + * cpu_mmu_index: + * @env: The cpu environment + * @ifetch: True for code access, false for data access. + * + * Return the core mmu index for the current translation regime. + * This function is used by generic TCG code paths. + */ +static inline int cpu_mmu_index(CPUARMState *env, bool ifetch) +{ + return FIELD_EX32(env->hflags, TBFLAG_ANY, MMUIDX); +} + static inline bool bswap_code(bool sctlr_b) { #ifdef CONFIG_USER_ONLY diff --git a/target/arm/helper.c b/target/arm/helper.c index c1dae83700..7cf6642210 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -12109,11 +12109,6 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env) return arm_mmu_idx_el(env, arm_current_el(env)); } -int cpu_mmu_index(CPUARMState *env, bool ifetch) -{ - return arm_to_core_mmu_idx(arm_mmu_idx(env)); -} - #ifndef CONFIG_USER_ONLY ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env) { -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/8] target/arm: Apply TBI to ESR_ELx in helper_exception_return 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson @ 2020-02-25 3:14 ` Richard Henderson 2020-03-02 12:08 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 4/8] target/arm: Move helper_dc_zva to helper-a64.c Richard Henderson ` (5 subsequent siblings) 6 siblings, 1 reply; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:14 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm We missed this case within AArch64.ExceptionReturn. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/helper-a64.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index 509ae93069..95e9e879ca 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -1031,6 +1031,8 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) "AArch32 EL%d PC 0x%" PRIx32 "\n", cur_el, new_el, env->regs[15]); } else { + int tbii; + env->aarch64 = 1; spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar); pstate_write(env, spsr); @@ -1038,8 +1040,27 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) env->pstate &= ~PSTATE_SS; } aarch64_restore_sp(env, new_el); - env->pc = new_pc; helper_rebuild_hflags_a64(env, new_el); + + /* + * Apply TBI to the exception return address. We had to delay this + * until after we selected the new EL, so that we could select the + * correct TBI+TBID bits. This is made easier by waiting until after + * the hflags rebuild, since we can pull the composite TBII field + * from there. + */ + tbii = FIELD_EX32(env->hflags, TBFLAG_A64, TBII); + if ((tbii >> extract64(new_pc, 55, 1)) & 1) { + /* TBI is enabled. */ + int core_mmu_idx = cpu_mmu_index(env, false); + if (regime_has_2_ranges(core_mmu_idx | ARM_MMU_IDX_A)) { + new_pc = sextract64(new_pc, 0, 56); + } else { + new_pc = extract64(new_pc, 0, 56); + } + } + env->pc = new_pc; + qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to " "AArch64 EL%d PC 0x%" PRIx64 "\n", cur_el, new_el, env->pc); -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 3/8] target/arm: Apply TBI to ESR_ELx in helper_exception_return 2020-02-25 3:14 ` [PATCH 3/8] target/arm: Apply TBI to ESR_ELx in helper_exception_return Richard Henderson @ 2020-03-02 12:08 ` Peter Maydell 0 siblings, 0 replies; 16+ messages in thread From: Peter Maydell @ 2020-03-02 12:08 UTC (permalink / raw) To: Richard Henderson; +Cc: qemu-arm, QEMU Developers On Tue, 25 Feb 2020 at 03:14, Richard Henderson <richard.henderson@linaro.org> wrote: > > We missed this case within AArch64.ExceptionReturn. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/helper-a64.c | 23 ++++++++++++++++++++++- > 1 file changed, 22 insertions(+), 1 deletion(-) > > diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c > index 509ae93069..95e9e879ca 100644 > --- a/target/arm/helper-a64.c > +++ b/target/arm/helper-a64.c > @@ -1031,6 +1031,8 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) > "AArch32 EL%d PC 0x%" PRIx32 "\n", > cur_el, new_el, env->regs[15]); > } else { > + int tbii; > + > env->aarch64 = 1; > spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar); > pstate_write(env, spsr); > @@ -1038,8 +1040,27 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) > env->pstate &= ~PSTATE_SS; > } > aarch64_restore_sp(env, new_el); > - env->pc = new_pc; > helper_rebuild_hflags_a64(env, new_el); > + > + /* > + * Apply TBI to the exception return address. We had to delay this > + * until after we selected the new EL, so that we could select the > + * correct TBI+TBID bits. This is made easier by waiting until after > + * the hflags rebuild, since we can pull the composite TBII field > + * from there. > + */ > + tbii = FIELD_EX32(env->hflags, TBFLAG_A64, TBII); > + if ((tbii >> extract64(new_pc, 55, 1)) & 1) { > + /* TBI is enabled. */ > + int core_mmu_idx = cpu_mmu_index(env, false); > + if (regime_has_2_ranges(core_mmu_idx | ARM_MMU_IDX_A)) { We have core_to_arm_mmu_idx() so you don't need to open-code this. Or just call arm_mmu_idx(env) to get the ARMMMUIdx directly. > + new_pc = sextract64(new_pc, 0, 56); > + } else { > + new_pc = extract64(new_pc, 0, 56); > + } > + } > + env->pc = new_pc; > + > qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to " > "AArch64 EL%d PC 0x%" PRIx64 "\n", > cur_el, new_el, env->pc); thanks -- PMM ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 4/8] target/arm: Move helper_dc_zva to helper-a64.c 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson 2020-02-25 3:14 ` [PATCH 3/8] target/arm: Apply TBI to ESR_ELx in helper_exception_return Richard Henderson @ 2020-02-25 3:14 ` Richard Henderson 2020-03-02 12:08 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 5/8] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva Richard Henderson ` (4 subsequent siblings) 6 siblings, 1 reply; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:14 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm This is an aarch64-only function. Move it out of the shared file. This patch is code movement only. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/helper-a64.h | 1 + target/arm/helper.h | 1 - target/arm/helper-a64.c | 91 ++++++++++++++++++++++++++++++++++++++++ target/arm/op_helper.c | 93 ----------------------------------------- 4 files changed, 92 insertions(+), 94 deletions(-) diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h index a915c1247f..b1a5935f61 100644 --- a/target/arm/helper-a64.h +++ b/target/arm/helper-a64.h @@ -90,6 +90,7 @@ DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr) DEF_HELPER_2(sqrt_f16, f16, f16, ptr) DEF_HELPER_2(exception_return, void, env, i64) +DEF_HELPER_2(dc_zva, void, env, i64) DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64) DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64) diff --git a/target/arm/helper.h b/target/arm/helper.h index fcbf504121..72eb9e6a1a 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -559,7 +559,6 @@ DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32) DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32) -DEF_HELPER_2(dc_zva, void, env, i64) DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index 95e9e879ca..c0a40c5fa9 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "cpu.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" @@ -1109,4 +1110,94 @@ uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp) return float16_sqrt(a, s); } +void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) +{ + /* + * Implement DC ZVA, which zeroes a fixed-length block of memory. + * Note that we do not implement the (architecturally mandated) + * alignment fault for attempts to use this on Device memory + * (which matches the usual QEMU behaviour of not implementing either + * alignment faults or any memory attribute handling). + */ + ARMCPU *cpu = env_archcpu(env); + uint64_t blocklen = 4 << cpu->dcz_blocksize; + uint64_t vaddr = vaddr_in & ~(blocklen - 1); + +#ifndef CONFIG_USER_ONLY + { + /* + * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than + * the block size so we might have to do more than one TLB lookup. + * We know that in fact for any v8 CPU the page size is at least 4K + * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only + * 1K as an artefact of legacy v5 subpage support being present in the + * same QEMU executable. So in practice the hostaddr[] array has + * two entries, given the current setting of TARGET_PAGE_BITS_MIN. + */ + int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE); + void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)]; + int try, i; + unsigned mmu_idx = cpu_mmu_index(env, false); + TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx); + + assert(maxidx <= ARRAY_SIZE(hostaddr)); + + for (try = 0; try < 2; try++) { + + for (i = 0; i < maxidx; i++) { + hostaddr[i] = tlb_vaddr_to_host(env, + vaddr + TARGET_PAGE_SIZE * i, + 1, mmu_idx); + if (!hostaddr[i]) { + break; + } + } + if (i == maxidx) { + /* + * If it's all in the TLB it's fair game for just writing to; + * we know we don't need to update dirty status, etc. + */ + for (i = 0; i < maxidx - 1; i++) { + memset(hostaddr[i], 0, TARGET_PAGE_SIZE); + } + memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE)); + return; + } + /* + * OK, try a store and see if we can populate the tlb. This + * might cause an exception if the memory isn't writable, + * in which case we will longjmp out of here. We must for + * this purpose use the actual register value passed to us + * so that we get the fault address right. + */ + helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC()); + /* Now we can populate the other TLB entries, if any */ + for (i = 0; i < maxidx; i++) { + uint64_t va = vaddr + TARGET_PAGE_SIZE * i; + if (va != (vaddr_in & TARGET_PAGE_MASK)) { + helper_ret_stb_mmu(env, va, 0, oi, GETPC()); + } + } + } + + /* + * Slow path (probably attempt to do this to an I/O device or + * similar, or clearing of a block of code we have translations + * cached for). Just do a series of byte writes as the architecture + * demands. It's not worth trying to use a cpu_physical_memory_map(), + * memset(), unmap() sequence here because: + * + we'd need to account for the blocksize being larger than a page + * + the direct-RAM access case is almost always going to be dealt + * with in the fastpath code above, so there's no speed benefit + * + we would have to deal with the map returning NULL because the + * bounce buffer was in use + */ + for (i = 0; i < blocklen; i++) { + helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC()); + } + } +#else + memset(g2h(vaddr), 0, blocklen); +#endif +} diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index af3020b78f..eb0de080f1 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -17,7 +17,6 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" -#include "qemu/units.h" #include "qemu/log.h" #include "qemu/main-loop.h" #include "cpu.h" @@ -936,95 +935,3 @@ uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i) return ((uint32_t)x >> shift) | (x << (32 - shift)); } } - -void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) -{ - /* - * Implement DC ZVA, which zeroes a fixed-length block of memory. - * Note that we do not implement the (architecturally mandated) - * alignment fault for attempts to use this on Device memory - * (which matches the usual QEMU behaviour of not implementing either - * alignment faults or any memory attribute handling). - */ - - ARMCPU *cpu = env_archcpu(env); - uint64_t blocklen = 4 << cpu->dcz_blocksize; - uint64_t vaddr = vaddr_in & ~(blocklen - 1); - -#ifndef CONFIG_USER_ONLY - { - /* - * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than - * the block size so we might have to do more than one TLB lookup. - * We know that in fact for any v8 CPU the page size is at least 4K - * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only - * 1K as an artefact of legacy v5 subpage support being present in the - * same QEMU executable. So in practice the hostaddr[] array has - * two entries, given the current setting of TARGET_PAGE_BITS_MIN. - */ - int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE); - void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)]; - int try, i; - unsigned mmu_idx = cpu_mmu_index(env, false); - TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx); - - assert(maxidx <= ARRAY_SIZE(hostaddr)); - - for (try = 0; try < 2; try++) { - - for (i = 0; i < maxidx; i++) { - hostaddr[i] = tlb_vaddr_to_host(env, - vaddr + TARGET_PAGE_SIZE * i, - 1, mmu_idx); - if (!hostaddr[i]) { - break; - } - } - if (i == maxidx) { - /* - * If it's all in the TLB it's fair game for just writing to; - * we know we don't need to update dirty status, etc. - */ - for (i = 0; i < maxidx - 1; i++) { - memset(hostaddr[i], 0, TARGET_PAGE_SIZE); - } - memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE)); - return; - } - /* - * OK, try a store and see if we can populate the tlb. This - * might cause an exception if the memory isn't writable, - * in which case we will longjmp out of here. We must for - * this purpose use the actual register value passed to us - * so that we get the fault address right. - */ - helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC()); - /* Now we can populate the other TLB entries, if any */ - for (i = 0; i < maxidx; i++) { - uint64_t va = vaddr + TARGET_PAGE_SIZE * i; - if (va != (vaddr_in & TARGET_PAGE_MASK)) { - helper_ret_stb_mmu(env, va, 0, oi, GETPC()); - } - } - } - - /* - * Slow path (probably attempt to do this to an I/O device or - * similar, or clearing of a block of code we have translations - * cached for). Just do a series of byte writes as the architecture - * demands. It's not worth trying to use a cpu_physical_memory_map(), - * memset(), unmap() sequence here because: - * + we'd need to account for the blocksize being larger than a page - * + the direct-RAM access case is almost always going to be dealt - * with in the fastpath code above, so there's no speed benefit - * + we would have to deal with the map returning NULL because the - * bounce buffer was in use - */ - for (i = 0; i < blocklen; i++) { - helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC()); - } - } -#else - memset(g2h(vaddr), 0, blocklen); -#endif -} -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 4/8] target/arm: Move helper_dc_zva to helper-a64.c 2020-02-25 3:14 ` [PATCH 4/8] target/arm: Move helper_dc_zva to helper-a64.c Richard Henderson @ 2020-03-02 12:08 ` Peter Maydell 0 siblings, 0 replies; 16+ messages in thread From: Peter Maydell @ 2020-03-02 12:08 UTC (permalink / raw) To: Richard Henderson; +Cc: qemu-arm, QEMU Developers On Tue, 25 Feb 2020 at 03:14, Richard Henderson <richard.henderson@linaro.org> wrote: > > This is an aarch64-only function. Move it out of the shared file. > This patch is code movement only. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 5/8] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson 2020-02-25 3:14 ` [PATCH 3/8] target/arm: Apply TBI to ESR_ELx in helper_exception_return Richard Henderson 2020-02-25 3:14 ` [PATCH 4/8] target/arm: Move helper_dc_zva to helper-a64.c Richard Henderson @ 2020-02-25 3:14 ` Richard Henderson 2020-03-02 12:10 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 6/8] target/arm: Clean address for DC ZVA Richard Henderson ` (3 subsequent siblings) 6 siblings, 1 reply; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:14 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm The function does not write registers, and only reads them by implication via the exception path. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/helper-a64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h index b1a5935f61..3df7c185aa 100644 --- a/target/arm/helper-a64.h +++ b/target/arm/helper-a64.h @@ -90,7 +90,7 @@ DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr) DEF_HELPER_2(sqrt_f16, f16, f16, ptr) DEF_HELPER_2(exception_return, void, env, i64) -DEF_HELPER_2(dc_zva, void, env, i64) +DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64) DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64) DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64) -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 5/8] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva 2020-02-25 3:14 ` [PATCH 5/8] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva Richard Henderson @ 2020-03-02 12:10 ` Peter Maydell 0 siblings, 0 replies; 16+ messages in thread From: Peter Maydell @ 2020-03-02 12:10 UTC (permalink / raw) To: Richard Henderson; +Cc: qemu-arm, QEMU Developers On Tue, 25 Feb 2020 at 03:14, Richard Henderson <richard.henderson@linaro.org> wrote: > > The function does not write registers, and only reads them by > implication via the exception path. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/helper-a64.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h > index b1a5935f61..3df7c185aa 100644 > --- a/target/arm/helper-a64.h > +++ b/target/arm/helper-a64.h > @@ -90,7 +90,7 @@ DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr) > DEF_HELPER_2(sqrt_f16, f16, f16, ptr) > > DEF_HELPER_2(exception_return, void, env, i64) > -DEF_HELPER_2(dc_zva, void, env, i64) > +DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64) > > DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64) > DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64) > -- Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 6/8] target/arm: Clean address for DC ZVA 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson ` (2 preceding siblings ...) 2020-02-25 3:14 ` [PATCH 5/8] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva Richard Henderson @ 2020-02-25 3:14 ` Richard Henderson 2020-02-25 3:14 ` [PATCH 7/8] target/arm: Check addresses for disabled regimes Richard Henderson ` (2 subsequent siblings) 6 siblings, 0 replies; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:14 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm This data access was forgotten when we added support for cleaning addresses of TBI information. Fixes: 3a471103ac1823ba Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/translate-a64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 596bf4cf73..24c1fbd262 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1784,7 +1784,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread, return; case ARM_CP_DC_ZVA: /* Writes clear the aligned block of memory which rt points into. */ - tcg_rt = cpu_reg(s, rt); + tcg_rt = clean_data_tbi(s, cpu_reg(s, rt)); gen_helper_dc_zva(cpu_env, tcg_rt); return; default: -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 7/8] target/arm: Check addresses for disabled regimes 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson ` (3 preceding siblings ...) 2020-02-25 3:14 ` [PATCH 6/8] target/arm: Clean address for DC ZVA Richard Henderson @ 2020-02-25 3:14 ` Richard Henderson 2020-02-25 3:14 ` [PATCH 8/8] target/arm: Disable clean_data_tbi for system mode Richard Henderson 2020-03-02 12:03 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Peter Maydell 6 siblings, 0 replies; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:14 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm We fail to validate the upper bits of a virtual address on a translation disabled regime, as per AArch64.TranslateAddressS1Off. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/helper.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 7cf6642210..2867adea29 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11615,7 +11615,38 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, /* Definitely a real MMU, not an MPU */ if (regime_translation_disabled(env, mmu_idx)) { - /* MMU disabled. */ + /* + * MMU disabled. S1 addresses are still checked for bounds. + * C.f. AArch64.TranslateAddressS1Off. + */ + if (is_a64(env) && mmu_idx != ARMMMUIdx_Stage2) { + int pamax = arm_pamax(env_archcpu(env)); + uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr; + int addrtop, tbi; + + tbi = aa64_va_parameter_tbi(tcr, mmu_idx); + if (access_type == MMU_INST_FETCH) { + tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx); + } + tbi = (tbi >> extract64(address, 55, 1)) & 1; + addrtop = (tbi ? 55 : 63); + + if (extract64(address, pamax, addrtop - pamax + 1) != 0) { + fi->type = ARMFault_AddressSize; + fi->level = 0; + fi->stage2 = false; + return 1; + } + + /* + * The ARM pseudocode copies bits [51:0] to addrdesc.paddress. + * Except for TBI, we've just validated everything above PAMax + * is zero. So we only need to drop TBI. + */ + if (tbi) { + address = extract64(address, 0, 56); + } + } *phys_ptr = address; *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; *page_size = TARGET_PAGE_SIZE; -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 8/8] target/arm: Disable clean_data_tbi for system mode 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson ` (4 preceding siblings ...) 2020-02-25 3:14 ` [PATCH 7/8] target/arm: Check addresses for disabled regimes Richard Henderson @ 2020-02-25 3:14 ` Richard Henderson 2020-03-02 12:03 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Peter Maydell 6 siblings, 0 replies; 16+ messages in thread From: Richard Henderson @ 2020-02-25 3:14 UTC (permalink / raw) To: qemu-devel; +Cc: peter.maydell, qemu-arm We must include the tag in the FAR_ELx register when raising an addressing exception. Which means that we should not clear out the tag during translation. We cannot at present comply with this for user mode, so we retain the clean_data_tbi function for the moment, though it no longer does what it says on the tin for system mode. This function is to be replaced with MTE, so don't worry about the slight misnaming. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/translate-a64.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 24c1fbd262..3c9c43926c 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -228,7 +228,18 @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src) static TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr) { TCGv_i64 clean = new_tmp_a64(s); + /* + * In order to get the correct value in the FAR_ELx register, + * we must present the memory subsystem with the "dirty" address + * including the TBI. In system mode we can make this work via + * the TLB, dropping the TBI during translation. But for user-only + * mode we don't have that option, and must remove the top byte now. + */ +#ifdef CONFIG_USER_ONLY gen_top_byte_ignore(s, clean, addr, s->tbid); +#else + tcg_gen_mov_i64(clean, addr); +#endif return clean; } -- 2.20.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 2/8] target/arm: Optimize cpu_mmu_index 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson ` (5 preceding siblings ...) 2020-02-25 3:14 ` [PATCH 8/8] target/arm: Disable clean_data_tbi for system mode Richard Henderson @ 2020-03-02 12:03 ` Peter Maydell 2020-03-02 16:24 ` Richard Henderson 6 siblings, 1 reply; 16+ messages in thread From: Peter Maydell @ 2020-03-02 12:03 UTC (permalink / raw) To: Richard Henderson; +Cc: qemu-arm, QEMU Developers On Tue, 25 Feb 2020 at 03:14, Richard Henderson <richard.henderson@linaro.org> wrote: > > We now cache the core mmu_idx in env->hflags. Rather than recompute > from scratch, extract the field. All of the uses of cpu_mmu_index > within target/arm are within helpers where env->hflags is stable. Do you mean "within helpers, and env->hflags is always stable in a helper", or "within helpers, and env->hflags is stable for the particular set of helpers where we use cpu_mmu_index, though it might not be in other helpers" ? thanks -- PMM ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/8] target/arm: Optimize cpu_mmu_index 2020-03-02 12:03 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Peter Maydell @ 2020-03-02 16:24 ` Richard Henderson 0 siblings, 0 replies; 16+ messages in thread From: Richard Henderson @ 2020-03-02 16:24 UTC (permalink / raw) To: Peter Maydell; +Cc: qemu-arm, QEMU Developers On 3/2/20 4:03 AM, Peter Maydell wrote: > On Tue, 25 Feb 2020 at 03:14, Richard Henderson > <richard.henderson@linaro.org> wrote: >> >> We now cache the core mmu_idx in env->hflags. Rather than recompute >> from scratch, extract the field. All of the uses of cpu_mmu_index >> within target/arm are within helpers where env->hflags is stable. > > Do you mean "within helpers, and env->hflags is always stable in > a helper", or "within helpers, and env->hflags is stable for the > particular set of helpers where we use cpu_mmu_index, though it might > not be in other helpers" ? The former. With the caveat that it's pretty clear when a helper is doing things that make it the exception to that rule. E.g. helper_exception_return, which itself invokes rebuild_hflags. r~ ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/8] target/arm: Misc cleanups surrounding TBI 2020-02-25 3:12 [PATCH 0/8] target/arm: Misc cleanups surrounding TBI Richard Henderson 2020-02-25 3:12 ` [PATCH 1/8] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson @ 2020-03-02 11:56 ` Peter Maydell 2 siblings, 0 replies; 16+ messages in thread From: Peter Maydell @ 2020-03-02 11:56 UTC (permalink / raw) To: Richard Henderson; +Cc: qemu-arm, QEMU Developers On Tue, 25 Feb 2020 at 03:12, Richard Henderson <richard.henderson@linaro.org> wrote: > > We have a bug at present wherein we do not supply the memory tag to > the memory system, so that on fault FAR_ELx does not contain the > correct value. > > For system mode, we already handle ignoring TBI in get_phys_addr_lpae, > as long as we don't actually drop the tag during translation. > For user mode, we don't have that option, so for now we must simply > accept that we'll get the wrong value in the siginfo_t. Something weird happened to this series: it looks like the first 2 patches were sent as replies to the cover letter, but then patches 3-8 were all replies to patch 2: https://lists.gnu.org/archive/html/qemu-devel/2020-02/msg06699.html The result is that neither patches nor patchew think they got the entire series. Could you resend it, please? thanks -- PMM ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2020-03-02 16:25 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-02-25 3:12 [PATCH 0/8] target/arm: Misc cleanups surrounding TBI Richard Henderson 2020-02-25 3:12 ` [PATCH 1/8] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson 2020-03-02 12:00 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Richard Henderson 2020-02-25 3:14 ` [PATCH 3/8] target/arm: Apply TBI to ESR_ELx in helper_exception_return Richard Henderson 2020-03-02 12:08 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 4/8] target/arm: Move helper_dc_zva to helper-a64.c Richard Henderson 2020-03-02 12:08 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 5/8] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva Richard Henderson 2020-03-02 12:10 ` Peter Maydell 2020-02-25 3:14 ` [PATCH 6/8] target/arm: Clean address for DC ZVA Richard Henderson 2020-02-25 3:14 ` [PATCH 7/8] target/arm: Check addresses for disabled regimes Richard Henderson 2020-02-25 3:14 ` [PATCH 8/8] target/arm: Disable clean_data_tbi for system mode Richard Henderson 2020-03-02 12:03 ` [PATCH 2/8] target/arm: Optimize cpu_mmu_index Peter Maydell 2020-03-02 16:24 ` Richard Henderson 2020-03-02 11:56 ` [PATCH 0/8] target/arm: Misc cleanups surrounding TBI Peter Maydell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).