aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/tcg/translate.c
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2023-03-15 03:04:07 +0100
committerThomas Huth <thuth@redhat.com>2023-03-20 09:32:50 +0100
commit199c42a6a16ba32b5684e679df949cf29024b0cf (patch)
treed77d46b4911a089e4222a70b65690333b1dff61f /target/s390x/tcg/translate.c
parent377dc84e2d58a734f9b9d299f218c4111133addb (diff)
target/s390x: Implement Early Exception Recognition
Generate a specification exception if a reserved bit is set in the PSW mask or if the PSW address is out of bounds dictated by the addressing mode. Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Message-Id: <20230315020408.384766-3-iii@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'target/s390x/tcg/translate.c')
-rw-r--r--target/s390x/tcg/translate.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 2e1e7e046a..7832cf02a6 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -4068,9 +4068,23 @@ static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
+static void gen_check_psw_mask(DisasContext *s)
+{
+ TCGv_i64 reserved = tcg_temp_new_i64();
+ TCGLabel *ok = gen_new_label();
+
+ tcg_gen_andi_i64(reserved, psw_mask, PSW_MASK_RESERVED);
+ tcg_gen_brcondi_i64(TCG_COND_EQ, reserved, 0, ok);
+ gen_program_exception(s, PGM_SPECIFICATION);
+ gen_set_label(ok);
+}
+
static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
{
tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
+
+ gen_check_psw_mask(s);
+
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
s->exit_to_mainloop = true;
return DISAS_TOO_MANY;
@@ -4331,6 +4345,8 @@ static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
}
+ gen_check_psw_mask(s);
+
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
s->exit_to_mainloop = true;
return DISAS_TOO_MANY;