diff options
author | David Hildenbrand <david@redhat.com> | 2017-12-08 17:01:59 +0100 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2017-12-14 17:56:54 +0100 |
commit | 0e9383bca8b92c4b457a46af0e351b7712984622 (patch) | |
tree | 8a86d4da698b3a6e81173919deaa8f96b0967840 /target/s390x/translate.c | |
parent | 5a59bc1de21921996545574822e92004629dbd37 (diff) | |
download | qemu-0e9383bca8b92c4b457a46af0e351b7712984622.zip qemu-0e9383bca8b92c4b457a46af0e351b7712984622.tar.gz qemu-0e9383bca8b92c4b457a46af0e351b7712984622.tar.bz2 |
s390x/tcg: ASI/ASGI/ALSI/ALSGI are atomic with Interlocked-acccess facility 1
The semantics of ASI/ASGI/ALSI/ALSGI changed. Let's implement them just
like LOAD AND ADD, so they are atomic. Emulate old behavior.
This fixes random crashes when booting a Linux kernel compiled for
z196+ with SMP + MTTCG.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20171208160207.26494-7-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/translate.c')
-rw-r--r-- | target/s390x/translate.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 08c1ace..7ab8e85 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -1364,6 +1364,27 @@ 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(); + + if (!s390_has_feat(S390_FEAT_STFLE_45)) { + tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); + } else { + /* 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); + } + + /* Recompute also for atomic case: needed for setting CC. */ + tcg_gen_add_i64(o->out, o->in1, o->in2); + + if (!s390_has_feat(S390_FEAT_STFLE_45)) { + tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); + } + return NO_EXIT; +} + static ExitStatus op_aeb(DisasContext *s, DisasOps *o) { gen_helper_aeb(o->out, cpu_env, o->in1, o->in2); |