aboutsummaryrefslogtreecommitdiff
path: root/target/arm/cpu.c
diff options
context:
space:
mode:
authorJohn Högberg <john.hogberg@ericsson.com>2023-07-04 14:08:48 +0100
committerPeter Maydell <peter.maydell@linaro.org>2023-07-06 12:58:42 +0100
commit9719f125b803f4e0fda834cd74a60dfa4ca398e2 (patch)
treea03f14d4a158d37a04913d636a42aa59733c7bb7 /target/arm/cpu.c
parent1f51573f7925b80e79a29f87c7d9d6ead60960c0 (diff)
target/arm: Handle IC IVAU to improve compatibility with JITs
Unlike architectures with precise self-modifying code semantics (e.g. x86) ARM processors do not maintain coherency for instruction execution and memory, requiring an instruction synchronization barrier on every core that will execute the new code, and on many models also the explicit use of cache management instructions. While this is required to make JITs work on actual hardware, QEMU has gotten away with not handling this since it does not emulate caches, and unconditionally invalidates code whenever the softmmu or the user-mode page protection logic detects that code has been modified. Unfortunately the latter does not work in the face of dual-mapped code (a common W^X workaround), where one page is executable and the other is writable: user-mode has no way to connect one with the other as that is only known to the kernel and the emulated application. This commit works around the issue by telling software that instruction cache invalidation is required by clearing the CPR_EL0.DIC flag (regardless of whether the emulated processor needs it), and then invalidating code in IC IVAU instructions. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1034 Co-authored-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: John Högberg <john.hogberg@ericsson.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 168778890374.24232.3402138851538068785-1@git.sr.ht [PMM: removed unnecessary AArch64 feature check; moved "clear CTR_EL1.DIC" code up a bit so it's not in the middle of the vfp/neon related tests] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/cpu.c')
-rw-r--r--target/arm/cpu.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index adf84f9686..822efa5b2c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1694,6 +1694,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
+#ifdef CONFIG_USER_ONLY
+ /*
+ * User mode relies on IC IVAU instructions to catch modification of
+ * dual-mapped code.
+ *
+ * Clear CTR_EL0.DIC to ensure that software that honors these flags uses
+ * IC IVAU even if the emulated processor does not normally require it.
+ */
+ cpu->ctr = FIELD_DP64(cpu->ctr, CTR_EL0, DIC, 0);
+#endif
+
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
cpu->has_vfp != cpu->has_neon) {
/*