aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/excp_helper.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2017-09-28 22:37:02 +0200
committerCornelia Huck <cohuck@redhat.com>2017-10-20 13:32:10 +0200
commitb1ab5f6068c059b1357209c1dbeaac772184977d (patch)
treee919bb321ea7e50b91ace07b7030d1fd58dac20e /target/s390x/excp_helper.c
parenta6880d213b371cec59f780ed16a99f0b1e0df88d (diff)
downloadqemu-b1ab5f6068c059b1357209c1dbeaac772184977d.zip
qemu-b1ab5f6068c059b1357209c1dbeaac772184977d.tar.gz
qemu-b1ab5f6068c059b1357209c1dbeaac772184977d.tar.bz2
s390x/tcg: implement STOP and RESET interrupts for TCG
Implement them like KVM implements/handles them. Both can only be triggered via SIGP instructions. RESET has (almost) the lowest priority if the CPU is running, and the highest if the CPU is STOPPED. This is handled in SIGP code already. On delivery, we only have to care about the "CPU running" scenario. STOP is defined to be delivered after all other interrupts have been delivered. Therefore it has the actual lowest priority. As both can wake up a CPU if sleeping, indicate them correctly to external code (e.g. cpu_has_work()). Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20170928203708.9376-25-david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/excp_helper.c')
-rw-r--r--target/s390x/excp_helper.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 56331ae..cff308a 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -450,6 +450,14 @@ void s390_cpu_do_interrupt(CPUState *cs)
if (cs->exception_index == -1 && s390_cpu_has_io_int(cpu)) {
cs->exception_index = EXCP_IO;
}
+ /* RESTART interrupt */
+ if (cs->exception_index == -1 && s390_cpu_has_restart_int(cpu)) {
+ cs->exception_index = EXCP_RESTART;
+ }
+ /* STOP interrupt has least priority */
+ if (cs->exception_index == -1 && s390_cpu_has_stop_int(cpu)) {
+ cs->exception_index = EXCP_STOP;
+ }
switch (cs->exception_index) {
case EXCP_PGM:
@@ -467,9 +475,15 @@ void s390_cpu_do_interrupt(CPUState *cs)
case EXCP_MCHK:
do_mchk_interrupt(env);
break;
+ case EXCP_RESTART:
+ do_restart_interrupt(env);
+ break;
+ case EXCP_STOP:
+ do_stop_interrupt(env);
+ break;
}
- /* WAIT PSW during interrupt injection */
+ /* WAIT PSW during interrupt injection or STOP interrupt */
if (cs->exception_index == EXCP_HLT) {
/* don't trigger a cpu_loop_exit(), use an interrupt instead */
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT);