+void HELPER(hstr_trap_check)(CPUARMState *env, uint32_t mask, uint32_t
syndrome)
+{
+ if (env->cp15.hstr_el2 & mask) {
+ raise_exception(env, EXCP_UDEF, syndrome, 2);
+ }
@@ -4760,6 +4761,28 @@ static void do_coproc_insn(DisasContext *s, int cpnum,
int is64,
break;
}
+ if (s->hstr_active && cpnum == 15 && s->current_el == 1) {
+ /*
+ * At EL1, check for a HSTR_EL2 trap, which must take precedence
+ * over the UNDEF for "no such register" or the UNDEF for "access
+ * permissions forbid this EL1 access". HSTR_EL2 traps from EL0
+ * only happen if the cpreg doesn't UNDEF at EL0, so we do those in
+ * access_check_cp_reg(), after the checks for whether the access
+ * configurably trapped to EL1.
+ */
+ uint32_t maskbit = is64 ? crm : crn;
+
+ if (maskbit != 4 && maskbit != 14) {
+ /* T4 and T14 are RES0 so never cause traps */
+ gen_set_condexec(s);
+ gen_update_pc(s, 0);
+ emitted_update_pc = true;
+ gen_helper_hstr_trap_check(cpu_env,
+ tcg_constant_i32(1 << maskbit),
+ tcg_constant_i32(syndrome));
+ }