aboutsummaryrefslogtreecommitdiff
path: root/target/arm
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-01-09 14:43:48 +0000
committerPeter Maydell <peter.maydell@linaro.org>2024-01-09 14:43:48 +0000
commit44572fc984b5fb80a2fe05f22e7146d55733eed1 (patch)
tree3693f54747e3b1ce01cd4e16925550b8dccdbc3c /target/arm
parent83aea11db036f18e60cb2bb10383e4bcdb1e4b08 (diff)
downloadqemu-44572fc984b5fb80a2fe05f22e7146d55733eed1.zip
qemu-44572fc984b5fb80a2fe05f22e7146d55733eed1.tar.gz
qemu-44572fc984b5fb80a2fe05f22e7146d55733eed1.tar.bz2
target/arm: Move FPU/SVE/SME access checks up above ARM_CP_SPECIAL_MASK check
In handle_sys() we don't do the check for whether the register is marked as needing an FPU/SVE/SME access check until after we've handled the special cases covered by ARM_CP_SPECIAL_MASK. This is conceptually the wrong way around, because if for example we happen to implement an FPU-access-checked register as ARM_CP_NOP, we should do the access check first. Move the access checks up so they are with all the other access checks, not sandwiched between the special-case read/write handling and the normal-case read/write handling. This doesn't change behaviour at the moment, because we happen not to define any cpregs with both ARM_CPU_{FPU,SVE,SME} and one of the cases dealt with by ARM_CP_SPECIAL_MASK. Moving this code also means we have the correct place to put the FEAT_NV/FEAT_NV2 access handling, which should come after the access checks and before we try to do any read/write action. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Miguel Luis <miguel.luis@oracle.com>
Diffstat (limited to 'target/arm')
-rw-r--r--target/arm/tcg/translate-a64.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 0f30e71..5975fc4 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -2190,6 +2190,14 @@ static void handle_sys(DisasContext *s, bool isread,
gen_a64_update_pc(s, 0);
}
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
+ return;
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
+ return;
+ } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
+ return;
+ }
+
/* Handle special cases first */
switch (ri->type & ARM_CP_SPECIAL_MASK) {
case 0:
@@ -2268,13 +2276,6 @@ static void handle_sys(DisasContext *s, bool isread,
default:
g_assert_not_reached();
}
- if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
- return;
- } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
- return;
- } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
- return;
- }
if (ri->type & ARM_CP_IO) {
/* I/O operations must end the TB here (whether read or write) */