target/s390x: Fix LRA overwriting the top 32 bits on DAT error

When a DAT error occurs, LRA is supposed to write the error information
to the bottom 32 bits of R1, and leave the top 32 bits of R1 alone.

Fix by passing the original value of R1 into helper and copying the
top 32 bits to the return value.

Fixes: d8fe4a9c28 ("target-s390: Convert LRA")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Cc: qemu-stable@nongnu.org
Message-Id: <20230704081506.276055-6-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
Ilya Leoshkevich 2023-07-04 10:12:29 +02:00 committed by Thomas Huth
parent 92a5753461
commit 6da311a60d
3 changed files with 4 additions and 4 deletions

View File

@ -355,7 +355,7 @@ DEF_HELPER_FLAGS_4(idte, TCG_CALL_NO_RWG, void, env, i64, i64, i32)
DEF_HELPER_FLAGS_4(ipte, TCG_CALL_NO_RWG, void, env, i64, i64, i32)
DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_1(purge, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_2(lra, i64, env, i64)
DEF_HELPER_3(lra, i64, env, i64, i64)
DEF_HELPER_1(per_check_exception, void, env)
DEF_HELPER_FLAGS_3(per_branch, TCG_CALL_NO_RWG, void, env, i64, i64)
DEF_HELPER_FLAGS_2(per_ifetch, TCG_CALL_NO_RWG, void, env, i64)

View File

@ -2356,7 +2356,7 @@ void HELPER(purge)(CPUS390XState *env)
}
/* load real address */
uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
uint64_t HELPER(lra)(CPUS390XState *env, uint64_t r1, uint64_t addr)
{
uint64_t asc = env->psw.mask & PSW_MASK_ASC;
uint64_t ret, tec;
@ -2370,7 +2370,7 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
exc = mmu_translate(env, addr, MMU_S390_LRA, asc, &ret, &flags, &tec);
if (exc) {
cc = 3;
ret = exc | 0x80000000;
ret = (r1 & 0xFFFFFFFF00000000ULL) | exc | 0x80000000;
} else {
cc = 0;
ret |= addr & ~TARGET_PAGE_MASK;

View File

@ -2932,7 +2932,7 @@ static DisasJumpType op_lctlg(DisasContext *s, DisasOps *o)
static DisasJumpType op_lra(DisasContext *s, DisasOps *o)
{
gen_helper_lra(o->out, cpu_env, o->in2);
gen_helper_lra(o->out, cpu_env, o->out, o->in2);
set_cc_static(s);
return DISAS_NEXT;
}