diff options
author | Thomas Huth <thuth@linux.vnet.ibm.com> | 2014-03-20 21:49:18 +0100 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2014-06-10 09:50:27 +0200 |
commit | a2689242b10a7bbc9a952659a2a5cc04a86d10e1 (patch) | |
tree | 8fa7b0018468c8eb2a6566d1f95999bdee18a4c1 /target-s390x | |
parent | 4cb88c3c378ae8c86c0ba53619caf6924f72239c (diff) |
s390x/kvm: Log unmanageable external interruptions
Interception code 0x14 only drops to userspace when an unmanageable
external interruption interception occured (e.g. if the External New
PSW does not disable external interruptions). Instead of bailing out
via the default handler, it is better to inform the user with a
proper error message that also includes the bad PSW, and to stop
the affected CPU with a panic event instead.
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/kvm.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 0a2a2052ee..be703bd87b 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -83,6 +83,7 @@ #define DIAG_KVM_BREAKPOINT 0x501 #define ICPT_INSTRUCTION 0x04 +#define ICPT_EXT_INT 0x14 #define ICPT_WAITPSW 0x1c #define ICPT_SOFT_INTERCEPT 0x24 #define ICPT_CPU_STOP 0x28 @@ -930,6 +931,28 @@ static bool is_special_wait_psw(CPUState *cs) return cs->kvm_run->psw_addr == 0xfffUL; } +static void guest_panicked(void) +{ + QObject *data; + + data = qobject_from_jsonf("{ 'action': %s }", "pause"); + monitor_protocol_event(QEVENT_GUEST_PANICKED, data); + qobject_decref(data); + + vm_stop(RUN_STATE_GUEST_PANICKED); +} + +static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswoffset) +{ + CPUState *cs = CPU(cpu); + + error_report("Unmanageable %s! CPU%i new PSW: 0x%016lx:%016lx", + str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswoffset), + ldq_phys(cs->as, cpu->env.psa + pswoffset + 8)); + s390_del_running_cpu(cpu); + guest_panicked(); +} + static int handle_intercept(S390CPU *cpu) { CPUState *cs = CPU(cpu); @@ -943,18 +966,18 @@ static int handle_intercept(S390CPU *cpu) case ICPT_INSTRUCTION: r = handle_instruction(cpu, run); break; + case ICPT_EXT_INT: + unmanageable_intercept(cpu, "external interrupt", + offsetof(LowCore, external_new_psw)); + r = EXCP_HALTED; + break; case ICPT_WAITPSW: /* disabled wait, since enabled wait is handled in kernel */ if (s390_del_running_cpu(cpu) == 0) { if (is_special_wait_psw(cs)) { qemu_system_shutdown_request(); } else { - QObject *data; - - data = qobject_from_jsonf("{ 'action': %s }", "pause"); - monitor_protocol_event(QEVENT_GUEST_PANICKED, data); - qobject_decref(data); - vm_stop(RUN_STATE_GUEST_PANICKED); + guest_panicked(); } } r = EXCP_HALTED; |