* [PATCH v2 1/9] target/arm: Replicate TBI/TBID bits for single range regimes
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-02 23:51 ` Philippe Mathieu-Daudé
2020-03-02 17:58 ` [PATCH v2 2/9] target/arm: Optimize cpu_mmu_index Richard Henderson
` (8 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 6be9ffa09e..37ffe06c05 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10316,7 +10316,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;
}
}
@@ -10327,7 +10328,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] 20+ messages in thread
* Re: [PATCH v2 1/9] target/arm: Replicate TBI/TBID bits for single range regimes
2020-03-02 17:58 ` [PATCH v2 1/9] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson
@ 2020-03-02 23:51 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-02 23:51 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell, qemu-arm
On 3/2/20 6:58 PM, Richard Henderson 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.
>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 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 6be9ffa09e..37ffe06c05 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -10316,7 +10316,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;
> }
> }
>
> @@ -10327,7 +10328,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;
> }
> }
>
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 2/9] target/arm: Optimize cpu_mmu_index
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
2020-03-02 17:58 ` [PATCH v2 1/9] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-05 14:23 ` Peter Maydell
2020-03-02 17:58 ` [PATCH v2 3/9] target/arm: Introduce core_to_aa64_mmu_idx Richard Henderson
` (7 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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, and env->hflags is always stable
within a translation block from whence helpers are called.
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 0b84742b66..8f1b949c88 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2936,16 +2936,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,
@@ -3225,6 +3215,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 37ffe06c05..addbec91d8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12128,11 +12128,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] 20+ messages in thread
* [PATCH v2 3/9] target/arm: Introduce core_to_aa64_mmu_idx
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
2020-03-02 17:58 ` [PATCH v2 1/9] target/arm: Replicate TBI/TBID bits for single range regimes Richard Henderson
2020-03-02 17:58 ` [PATCH v2 2/9] target/arm: Optimize cpu_mmu_index Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-02 23:50 ` Philippe Mathieu-Daudé
2020-03-05 14:23 ` Peter Maydell
2020-03-02 17:58 ` [PATCH v2 4/9] target/arm: Apply TBI to ESR_ELx in helper_exception_return Richard Henderson
` (6 subsequent siblings)
9 siblings, 2 replies; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, qemu-arm
If by context we know that we're in AArch64 mode, we need not
test for M-profile when reconstructing the full ARMMMUIdx.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/internals.h | 6 ++++++
target/arm/translate-a64.c | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 9f96a2359f..e633aff36e 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -783,6 +783,12 @@ static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
}
}
+static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
+{
+ /* AArch64 is always a-profile. */
+ return mmu_idx | ARM_MMU_IDX_A;
+}
+
int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
/*
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 579180af0a..c910a49b4e 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14300,7 +14300,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->condexec_mask = 0;
dc->condexec_cond = 0;
core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
- dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
+ dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
--
2.20.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 3/9] target/arm: Introduce core_to_aa64_mmu_idx
2020-03-02 17:58 ` [PATCH v2 3/9] target/arm: Introduce core_to_aa64_mmu_idx Richard Henderson
@ 2020-03-02 23:50 ` Philippe Mathieu-Daudé
2020-03-05 14:23 ` Peter Maydell
1 sibling, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-02 23:50 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell, qemu-arm
On 3/2/20 6:58 PM, Richard Henderson wrote:
> If by context we know that we're in AArch64 mode, we need not
> test for M-profile when reconstructing the full ARMMMUIdx.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/internals.h | 6 ++++++
> target/arm/translate-a64.c | 2 +-
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/internals.h b/target/arm/internals.h
> index 9f96a2359f..e633aff36e 100644
> --- a/target/arm/internals.h
> +++ b/target/arm/internals.h
> @@ -783,6 +783,12 @@ static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
> }
> }
>
> +static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
> +{
> + /* AArch64 is always a-profile. */
> + return mmu_idx | ARM_MMU_IDX_A;
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> +}
> +
> int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
>
> /*
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 579180af0a..c910a49b4e 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -14300,7 +14300,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
> dc->condexec_mask = 0;
> dc->condexec_cond = 0;
> core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
> - dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
> + dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
> dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
> dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
> dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 3/9] target/arm: Introduce core_to_aa64_mmu_idx
2020-03-02 17:58 ` [PATCH v2 3/9] target/arm: Introduce core_to_aa64_mmu_idx Richard Henderson
2020-03-02 23:50 ` Philippe Mathieu-Daudé
@ 2020-03-05 14:23 ` Peter Maydell
1 sibling, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2020-03-05 14:23 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-arm, QEMU Developers
On Mon, 2 Mar 2020 at 17:58, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> If by context we know that we're in AArch64 mode, we need not
> test for M-profile when reconstructing the full ARMMMUIdx.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/internals.h | 6 ++++++
> target/arm/translate-a64.c | 2 +-
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/internals.h b/target/arm/internals.h
> index 9f96a2359f..e633aff36e 100644
> --- a/target/arm/internals.h
> +++ b/target/arm/internals.h
> @@ -783,6 +783,12 @@ static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
> }
> }
>
> +static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
> +{
> + /* AArch64 is always a-profile. */
> + return mmu_idx | ARM_MMU_IDX_A;
> +}
> +
> int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 4/9] target/arm: Apply TBI to ESR_ELx in helper_exception_return
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
` (2 preceding siblings ...)
2020-03-02 17:58 ` [PATCH v2 3/9] target/arm: Introduce core_to_aa64_mmu_idx Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-05 14:24 ` Peter Maydell
2020-03-02 17:58 ` [PATCH v2 5/9] target/arm: Move helper_dc_zva to helper-a64.c Richard Henderson
` (5 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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..123ce50e7a 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_to_aa64_mmu_idx(core_mmu_idx))) {
+ 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] 20+ messages in thread
* [PATCH v2 5/9] target/arm: Move helper_dc_zva to helper-a64.c
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
` (3 preceding siblings ...)
2020-03-02 17:58 ` [PATCH v2 4/9] target/arm: Apply TBI to ESR_ELx in helper_exception_return Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-02 23:52 ` Philippe Mathieu-Daudé
2020-03-02 17:58 ` [PATCH v2 6/9] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva Richard Henderson
` (4 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 123ce50e7a..bc0649a44a 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] 20+ messages in thread
* Re: [PATCH v2 5/9] target/arm: Move helper_dc_zva to helper-a64.c
2020-03-02 17:58 ` [PATCH v2 5/9] target/arm: Move helper_dc_zva to helper-a64.c Richard Henderson
@ 2020-03-02 23:52 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-02 23:52 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell, qemu-arm
On 3/2/20 6:58 PM, Richard Henderson wrote:
> This is an aarch64-only function. Move it out of the shared file.
> This patch is code movement only.
>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 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 123ce50e7a..bc0649a44a 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
> -}
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 6/9] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
` (4 preceding siblings ...)
2020-03-02 17:58 ` [PATCH v2 5/9] target/arm: Move helper_dc_zva to helper-a64.c Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-02 23:53 ` Philippe Mathieu-Daudé
2020-03-02 17:58 ` [PATCH v2 7/9] target/arm: Clean address for DC ZVA Richard Henderson
` (3 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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] 20+ messages in thread
* Re: [PATCH v2 6/9] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva
2020-03-02 17:58 ` [PATCH v2 6/9] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva Richard Henderson
@ 2020-03-02 23:53 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-02 23:53 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell, qemu-arm
On 3/2/20 6:58 PM, Richard Henderson wrote:
> The function does not write registers, and only reads them by
> implication via the exception path.
>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 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: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 7/9] target/arm: Clean address for DC ZVA
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
` (5 preceding siblings ...)
2020-03-02 17:58 ` [PATCH v2 6/9] target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-02 17:58 ` [PATCH v2 8/9] target/arm: Check addresses for disabled regimes Richard Henderson
` (2 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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 c910a49b4e..fefe8af7f5 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] 20+ messages in thread
* [PATCH v2 8/9] target/arm: Check addresses for disabled regimes
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
` (6 preceding siblings ...)
2020-03-02 17:58 ` [PATCH v2 7/9] target/arm: Clean address for DC ZVA Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-05 14:21 ` Peter Maydell
2020-03-02 17:58 ` [PATCH v2 9/9] target/arm: Disable clean_data_tbi for system mode Richard Henderson
2020-03-05 15:12 ` [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Peter Maydell
9 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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 addbec91d8..0ef32d3c24 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11634,7 +11634,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] 20+ messages in thread
* Re: [PATCH v2 8/9] target/arm: Check addresses for disabled regimes
2020-03-02 17:58 ` [PATCH v2 8/9] target/arm: Check addresses for disabled regimes Richard Henderson
@ 2020-03-05 14:21 ` Peter Maydell
2020-03-05 15:57 ` Richard Henderson
0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2020-03-05 14:21 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-arm, QEMU Developers
On Mon, 2 Mar 2020 at 17:58, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> 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 addbec91d8..0ef32d3c24 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -11634,7 +11634,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) {
This looks weird -- why do we care about whether the current
EL is aarch64, rather than looking at the controlling EL
for the translation regime ?
thanks
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 8/9] target/arm: Check addresses for disabled regimes
2020-03-05 14:21 ` Peter Maydell
@ 2020-03-05 15:57 ` Richard Henderson
0 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2020-03-05 15:57 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-arm, QEMU Developers
On 3/5/20 6:21 AM, Peter Maydell wrote:
>> 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) {
>
> This looks weird -- why do we care about whether the current
> EL is aarch64, rather than looking at the controlling EL
> for the translation regime ?
You're right, it should be the aa64-ness of the regime_el.
Thanks,
r~
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 9/9] target/arm: Disable clean_data_tbi for system mode
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
` (7 preceding siblings ...)
2020-03-02 17:58 ` [PATCH v2 8/9] target/arm: Check addresses for disabled regimes Richard Henderson
@ 2020-03-02 17:58 ` Richard Henderson
2020-03-05 15:12 ` [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Peter Maydell
9 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2020-03-02 17:58 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 fefe8af7f5..8fffb52203 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] 20+ messages in thread
* Re: [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI
2020-03-02 17:58 [PATCH v2 0/9] target/arm: Misc cleanups surrounding TBI Richard Henderson
` (8 preceding siblings ...)
2020-03-02 17:58 ` [PATCH v2 9/9] target/arm: Disable clean_data_tbi for system mode Richard Henderson
@ 2020-03-05 15:12 ` Peter Maydell
9 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2020-03-05 15:12 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-arm, QEMU Developers
On Mon, 2 Mar 2020 at 17:58, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Changes for v2:
> * Improve commit message in "Optimize cpu_mmu_index".
> * Add "Introduce core_to_aa64_mmu_idx".
> * Use it in "Apply TBI to ESR_ELx in helper_exception_return".
Applied 1-7 to target-arm.next, thanks.
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread