* [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
* [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
* [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
* [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
* [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 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
* 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
* 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 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
* 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
* 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
* 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
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).