[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[qemu-s390x] [PULL 05/46] s390x/tcg: injection of emergency signals and
From: |
Cornelia Huck |
Subject: |
[qemu-s390x] [PULL 05/46] s390x/tcg: injection of emergency signals and external calls |
Date: |
Fri, 20 Oct 2017 13:53:37 +0200 |
From: David Hildenbrand <address@hidden>
Preparation for new TCG SIGP code. Especially also prepare for
indicating that another external call is already pending.
Take care of interrupt priority.
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 | 8 +++++++-
target/s390x/excp_helper.c | 16 +++++++++++++++-
target/s390x/internal.h | 2 ++
target/s390x/interrupt.c | 26 ++++++++++++++++++++++++++
4 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7bea97a2d7..f0f5ff0359 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -126,6 +126,8 @@ struct CPUS390XState {
int pending_int;
uint32_t service_param;
+ uint16_t external_call_addr;
+ DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
int io_index[8];
int mchk_index;
@@ -401,9 +403,13 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState*
env, target_ulong *pc,
#define INTERRUPT_EXT_SERVICE (1 << 2)
#define INTERRUPT_EXT_CPU_TIMER (1 << 3)
#define INTERRUPT_EXT_CLOCK_COMPARATOR (1 << 4)
+#define INTERRUPT_EXTERNAL_CALL (1 << 5)
+#define INTERRUPT_EMERGENCY_SIGNAL (1 << 6)
#define INTERRUPT_EXT (INTERRUPT_EXT_SERVICE | \
INTERRUPT_EXT_CPU_TIMER | \
- INTERRUPT_EXT_CLOCK_COMPARATOR)
+ INTERRUPT_EXT_CLOCK_COMPARATOR | \
+ INTERRUPT_EXTERNAL_CALL | \
+ INTERRUPT_EMERGENCY_SIGNAL)
/* Program Status Word. */
#define S390_PSWM_REGNUM 0
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index f5851069b5..44e9b2c6a6 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -240,6 +240,7 @@ static void do_ext_interrupt(CPUS390XState *env)
{
S390CPU *cpu = s390_env_get_cpu(env);
uint64_t mask, addr;
+ uint16_t cpu_addr;
LowCore *lowcore;
if (!(env->psw.mask & PSW_MASK_EXT)) {
@@ -248,7 +249,20 @@ static void do_ext_interrupt(CPUS390XState *env)
lowcore = cpu_map_lowcore(env);
- if (env->pending_int & INTERRUPT_EXT_CLOCK_COMPARATOR) {
+ if (env->pending_int & INTERRUPT_EMERGENCY_SIGNAL) {
+ lowcore->ext_int_code = cpu_to_be16(EXT_EMERGENCY);
+ cpu_addr = find_first_bit(env->emergency_signals, S390_MAX_CPUS);
+ g_assert(cpu_addr < S390_MAX_CPUS);
+ lowcore->cpu_addr = cpu_to_be16(cpu_addr);
+ clear_bit(cpu_addr, env->emergency_signals);
+ if (bitmap_empty(env->emergency_signals, max_cpus)) {
+ env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL;
+ }
+ } else if (env->pending_int & INTERRUPT_EXTERNAL_CALL) {
+ lowcore->ext_int_code = cpu_to_be16(EXT_EXTERNAL_CALL);
+ lowcore->cpu_addr = cpu_to_be16(env->external_call_addr);
+ env->pending_int &= ~INTERRUPT_EXTERNAL_CALL;
+ } else if (env->pending_int & INTERRUPT_EXT_CLOCK_COMPARATOR) {
lowcore->ext_int_code = cpu_to_be16(EXT_CLOCK_COMP);
lowcore->cpu_addr = 0;
env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR;
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index eaa071a183..f67c2a1785 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -362,6 +362,8 @@ void cpu_unmap_lowcore(LowCore *lowcore);
void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen);
void cpu_inject_clock_comparator(S390CPU *cpu);
void cpu_inject_cpu_timer(S390CPU *cpu);
+void cpu_inject_emergency_signal(S390CPU *cpu, uint16_t src_cpu_addr);
+int cpu_inject_external_call(S390CPU *cpu, uint16_t src_cpu_addr);
/* ioinst.c */
diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
index edcc2e9d2d..bb7cc7f87f 100644
--- a/target/s390x/interrupt.c
+++ b/target/s390x/interrupt.c
@@ -81,6 +81,32 @@ void cpu_inject_cpu_timer(S390CPU *cpu)
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
}
+void cpu_inject_emergency_signal(S390CPU *cpu, uint16_t src_cpu_addr)
+{
+ CPUS390XState *env = &cpu->env;
+
+ g_assert(src_cpu_addr < S390_MAX_CPUS);
+ set_bit(src_cpu_addr, env->emergency_signals);
+
+ env->pending_int |= INTERRUPT_EMERGENCY_SIGNAL;
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
+int cpu_inject_external_call(S390CPU *cpu, uint16_t src_cpu_addr)
+{
+ CPUS390XState *env = &cpu->env;
+
+ g_assert(src_cpu_addr < S390_MAX_CPUS);
+ if (env->pending_int & INTERRUPT_EXTERNAL_CALL) {
+ return -EBUSY;
+ }
+ env->external_call_addr = src_cpu_addr;
+
+ env->pending_int |= INTERRUPT_EXTERNAL_CALL;
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+ return 0;
+}
+
static void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
uint16_t subchannel_number,
uint32_t io_int_parm, uint32_t io_int_word)
--
2.13.6
- [qemu-s390x] [PULL 00/46] more s390x patches for 2.11, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 02/46] s390x/css: be more consistent if broken beyond repair, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 01/46] S390: use g_new() family of functions, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 03/46] s390x/tcg: turn INTERRUPT_EXT into a mask, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 04/46] s390x/tcg: cleanup service interrupt injection, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 05/46] s390x/tcg: injection of emergency signals and external calls,
Cornelia Huck <=
- [qemu-s390x] [PULL 08/46] s390x/tcg: STOPPED cpus can never wake up, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 06/46] s390x/tcg: rework checking for deliverable interrupts, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 07/46] s390x/tcg: take care of external interrupt subclasses, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 09/46] s390x/tcg: a CPU cannot switch state due to an interrupt, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 11/46] s390x/tcg: handle WAIT PSWs during interrupt injection, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 10/46] target/s390x: factor out handling of WAIT PSW into s390_handle_wait(), Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 13/46] s390x/kvm: pass ipb directly into handle_sigp(), Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 12/46] target/s390x: interpret PSW_MASK_WAIT only for TCG, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 14/46] s390x/kvm: generalize SIGP stop and restart interrupt injection, Cornelia Huck, 2017/10/20
- [qemu-s390x] [PULL 15/46] s390x/kvm: factor out storing of CPU status, Cornelia Huck, 2017/10/20