summaryrefslogtreecommitdiffstats
path: root/target/arm/helper.c
diff options
context:
space:
mode:
authorMarc Zyngier2019-12-01 13:20:17 +0100
committerPeter Maydell2019-12-16 11:46:35 +0100
commit5bb0a20b74ad17dee5dae38e3b8b70b383ee7c2d (patch)
tree60d79a11f29636313eb7988539cecf1e627267c8 /target/arm/helper.c
parenttarget/arm: Handle trapping to EL2 of AArch32 VMRS instructions (diff)
downloadqemu-5bb0a20b74ad17dee5dae38e3b8b70b383ee7c2d.tar.gz
qemu-5bb0a20b74ad17dee5dae38e3b8b70b383ee7c2d.tar.xz
qemu-5bb0a20b74ad17dee5dae38e3b8b70b383ee7c2d.zip
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
HSTR_EL2 offers a way to trap ranges of CP15 system register accesses to EL2, and it looks like this register is completely ignored by QEMU. To avoid adding extra .accessfn filters all over the place (which would have a direct performance impact), let's add a new TB flag that gets set whenever HSTR_EL2 is non-zero and that QEMU translates a context where this trap has a chance to apply, and only generate the extra access check if the hypervisor is actively using this feature. Tested with a hand-crafted KVM guest accessing CBAR. Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20191201122018.25808-5-maz@kernel.org [PMM: use is_a64(); fix comment syntax] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/helper.c')
-rw-r--r--target/arm/helper.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 93ecab27c0..0ba08d550a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11283,6 +11283,12 @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
if (arm_el_is_aa64(env, 1)) {
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
}
+
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
+ }
+
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
}