diff options
author | David Hildenbrand <david@redhat.com> | 2017-09-28 22:37:08 +0200 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2017-10-20 13:32:10 +0200 |
commit | 741a4ec186160b632b6e19d2ad9623bc0121ea5d (patch) | |
tree | ef51ed709f0a17273b1034347cb5bba9f3f57b6c /target/s390x/cpu.c | |
parent | f74990a5d019751c545e9800a3376b6336e77d38 (diff) | |
download | qemu-741a4ec186160b632b6e19d2ad9623bc0121ea5d.zip qemu-741a4ec186160b632b6e19d2ad9623bc0121ea5d.tar.gz qemu-741a4ec186160b632b6e19d2ad9623bc0121ea5d.tar.bz2 |
target/s390x: special handling when starting a CPU with WAIT PSW
When we try to start a CPU with a WAIT PSW, we have to take care that
TCG will actually try to continue executing instructions.
We must therefore really only unhalt the CPU if we don't have a WAIT
PSW. Also document the special order for restart interrupts, which
load a new PSW and change the state to operating.
To keep KVM working, simply don't have a look at the WAIT bit when
loading the PSW. Otherwise the behavior of a restart interrupt when
a CPU stopped would be changed.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20170928203708.9376-31-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/cpu.c')
-rw-r--r-- | target/s390x/cpu.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 92f6707..95f4283 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -337,8 +337,15 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu) break; case CPU_STATE_OPERATING: case CPU_STATE_LOAD: - /* unhalt the cpu for common infrastructure */ - s390_cpu_unhalt(cpu); + /* + * Starting a CPU with a PSW WAIT bit set: + * KVM: handles this internally and triggers another WAIT exit. + * TCG: will actually try to continue to run. Don't unhalt, will + * be done when the CPU actually has work (an interrupt). + */ + if (!tcg_enabled() || !(cpu->env.psw.mask & PSW_MASK_WAIT)) { + s390_cpu_unhalt(cpu); + } break; default: error_report("Requested CPU state is not a valid S390 CPU state: %u", |