[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[qemu-s390x] [PULL 25/46] s390x/tcg: implement STOP and RESET interrupts
From: |
Cornelia Huck |
Subject: |
[qemu-s390x] [PULL 25/46] s390x/tcg: implement STOP and RESET interrupts for TCG |
Date: |
Fri, 20 Oct 2017 13:53:57 +0200 |
From: David Hildenbrand <address@hidden>
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 <address@hidden>
Message-Id: <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
Signed-off-by: Cornelia Huck <address@hidden>
---
target/s390x/cpu.h | 4 ++++
target/s390x/excp_helper.c | 16 +++++++++++++++-
target/s390x/helper.c | 1 +
target/s390x/internal.h | 2 ++
target/s390x/interrupt.c | 32 +++++++++++++++++++++++++++-----
target/s390x/sigp.c | 2 ++
6 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7f4f03f410..b684502900 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -400,6 +400,8 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env,
target_ulong *pc,
#define EXCP_EXT 1 /* external interrupt */
#define EXCP_SVC 2 /* supervisor call (syscall) */
#define EXCP_PGM 3 /* program interruption */
+#define EXCP_RESTART 4 /* restart interrupt */
+#define EXCP_STOP 5 /* stop interrupt */
#define EXCP_IO 7 /* I/O interrupt */
#define EXCP_MCHK 8 /* machine check */
@@ -410,6 +412,8 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env,
target_ulong *pc,
#define INTERRUPT_EXT_CLOCK_COMPARATOR (1 << 4)
#define INTERRUPT_EXTERNAL_CALL (1 << 5)
#define INTERRUPT_EMERGENCY_SIGNAL (1 << 6)
+#define INTERRUPT_RESTART (1 << 7)
+#define INTERRUPT_STOP (1 << 8)
/* Program Status Word. */
#define S390_PSWM_REGNUM 0
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 56331ae4fb..cff308a18d 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);
diff --git a/target/s390x/helper.c b/target/s390x/helper.c
index 2505f3aec0..c41aa4c4ff 100644
--- a/target/s390x/helper.c
+++ b/target/s390x/helper.c
@@ -202,6 +202,7 @@ void do_restart_interrupt(CPUS390XState *env)
addr = be64_to_cpu(lowcore->restart_new_psw.addr);
cpu_unmap_lowcore(lowcore);
+ env->pending_int &= ~INTERRUPT_RESTART;
load_psw(env, mask, addr);
}
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 2c3fc3fce0..3aff54ada4 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -372,6 +372,8 @@ bool s390_cpu_has_io_int(S390CPU *cpu);
bool s390_cpu_has_ext_int(S390CPU *cpu);
bool s390_cpu_has_mcck_int(S390CPU *cpu);
bool s390_cpu_has_int(S390CPU *cpu);
+bool s390_cpu_has_restart_int(S390CPU *cpu);
+bool s390_cpu_has_stop_int(S390CPU *cpu);
void cpu_inject_restart(S390CPU *cpu);
void cpu_inject_stop(S390CPU *cpu);
diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
index 462d45e95f..ce6177c141 100644
--- a/target/s390x/interrupt.c
+++ b/target/s390x/interrupt.c
@@ -109,22 +109,28 @@ int cpu_inject_external_call(S390CPU *cpu, uint16_t
src_cpu_addr)
void cpu_inject_restart(S390CPU *cpu)
{
+ CPUS390XState *env = &cpu->env;
+
if (kvm_enabled()) {
kvm_s390_restart_interrupt(cpu);
return;
}
- /* FIXME TCG */
- g_assert_not_reached();
+
+ env->pending_int |= INTERRUPT_RESTART;
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
}
void cpu_inject_stop(S390CPU *cpu)
{
+ CPUS390XState *env = &cpu->env;
+
if (kvm_enabled()) {
kvm_s390_stop_interrupt(cpu);
return;
}
- /* FIXME TCG */
- g_assert_not_reached();
+
+ env->pending_int |= INTERRUPT_STOP;
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
}
static void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
@@ -272,6 +278,20 @@ bool s390_cpu_has_io_int(S390CPU *cpu)
return env->pending_int & INTERRUPT_IO;
}
+
+bool s390_cpu_has_restart_int(S390CPU *cpu)
+{
+ CPUS390XState *env = &cpu->env;
+
+ return env->pending_int & INTERRUPT_RESTART;
+}
+
+bool s390_cpu_has_stop_int(S390CPU *cpu)
+{
+ CPUS390XState *env = &cpu->env;
+
+ return env->pending_int & INTERRUPT_STOP;
+}
#endif
bool s390_cpu_has_int(S390CPU *cpu)
@@ -282,7 +302,9 @@ bool s390_cpu_has_int(S390CPU *cpu)
}
return s390_cpu_has_mcck_int(cpu) ||
s390_cpu_has_ext_int(cpu) ||
- s390_cpu_has_io_int(cpu);
+ s390_cpu_has_io_int(cpu) ||
+ s390_cpu_has_restart_int(cpu) ||
+ s390_cpu_has_stop_int(cpu);
#else
return false;
#endif
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
index ce8fda9d01..d70f5cb0ba 100644
--- a/target/s390x/sigp.c
+++ b/target/s390x/sigp.c
@@ -14,6 +14,7 @@
#include "internal.h"
#include "sysemu/hw_accel.h"
#include "exec/address-spaces.h"
+#include "exec/exec-all.h"
#include "sysemu/sysemu.h"
#include "trace.h"
@@ -498,6 +499,7 @@ void do_stop_interrupt(CPUS390XState *env)
s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
}
env->sigp_order = 0;
+ env->pending_int &= ~INTERRUPT_STOP;
}
void s390_init_sigp(void)
--
2.13.6
- [qemu-s390x] [PULL 15/46] s390x/kvm: factor out storing of CPU status, (continued)
- [qemu-s390x] [PULL 15/46] s390x/kvm: factor out storing of CPU status, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 17/46] s390x/kvm: drop two debug prints, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 16/46] s390x/kvm: factor out storing of adtl CPU status, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 19/46] s390x/kvm: factor out actual handling of STOP interrupts, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 21/46] s390x/tcg: implement SIGP SENSE, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 20/46] s390x/tcg: implement SIGP SENSE RUNNING STATUS, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 22/46] s390x/tcg: implement SIGP EXTERNAL CALL, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 18/46] s390x/kvm: factor out SIGP code into sigp.c, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 23/46] s390x/tcg: implement SIGP EMERGENCY SIGNAL, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 24/46] s390x/tcg: implement SIGP CONDITIONAL EMERGENCY SIGNAL, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 25/46] s390x/tcg: implement STOP and RESET interrupts for TCG,
Cornelia Huck <=
- [qemu-s390x] [PULL 26/46] s390x/tcg: flush the tlb on SIGP SET PREFIX, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 28/46] s390x/cpumodel: allow to enable SENSE RUNNING STATUS for qemu, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 27/46] s390x/tcg: switch to new SIGP handling code, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 30/46] s390x/tcg: refactor stfl(e) to use s390_get_feat_block(), Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 31/46] target/s390x: special handling when starting a CPU with WAIT PSW, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 29/46] s390x/tcg: unlock NMI, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 32/46] virtio-ccw: Add the virtio-input devices for CCW bus, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 33/46] s390x/MAINTAINERS: add mailing list, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 34/46] s390x/event-facility: variable-length event masks, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 35/46] s390x: fix cpu object referrence leak in s390x_new_cpu(), Cornelia Huck, 2017/10/20