The semantics of these operations changed. Let's implement them just like LOAD AND ADD, so they are atomic.
This fixes random crashes when booting a Linux kernel compiled for z196+ with SMP + MTTCG. Signed-off-by: David Hildenbrand <da...@redhat.com> --- target/s390x/insn-data.def | 4 ++-- target/s390x/translate.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 43ab1963c8..57f2e5133f 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -39,10 +39,10 @@ C(0xb9d8, AHHLR, RRF_a, HW, r2_sr32, r3, new, r1_32h, add, adds32) /* ADD IMMEDIATE */ C(0xc209, AFI, RIL_a, EI, r1, i2, new, r1_32, add, adds32) - C(0xeb6a, ASI, SIY, GIE, m1_32s, i2, new, m1_32, add, adds32) + D(0xeb6a, ASI, SIY, GIE, la1, i2, new, 0, asi, adds32, MO_TESL) C(0xecd8, AHIK, RIE_d, DO, r3, i2, new, r1_32, add, adds32) C(0xc208, AGFI, RIL_a, EI, r1, i2, r1, 0, add, adds64) - C(0xeb7a, AGSI, SIY, GIE, m1_64, i2, new, m1_64, add, adds64) + D(0xeb7a, AGSI, SIY, GIE, la1, i2, new, 0, asi, adds64, MO_TEQ) C(0xecd9, AGHIK, RIE_d, DO, r3, i2, r1, 0, add, adds64) /* ADD IMMEDIATE HIGH */ C(0xcc08, AIH, RIL_a, HW, r1_sr32, i2, new, r1_32h, add, adds32) diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 5e051fdd03..79d2ee650c 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -1364,6 +1364,17 @@ static ExitStatus op_addc(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_asi(DisasContext *s, DisasOps *o) +{ + o->in1 = tcg_temp_new_i64(); + /* Perform the atomic addition in memory. */ + tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s), + s->insn->data); + /* However, we need to recompute the addition for setting CC. */ + tcg_gen_add_i64(o->out, o->in1, o->in2); + return NO_EXIT; +} + static ExitStatus op_aeb(DisasContext *s, DisasOps *o) { gen_helper_aeb(o->out, cpu_env, o->in1, o->in2); -- 2.14.3