[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 02/13] s390x/kvm: detect some program check loops
From: |
Cornelia Huck |
Subject: |
[Qemu-devel] [PULL 02/13] s390x/kvm: detect some program check loops |
Date: |
Fri, 24 Feb 2017 10:22:48 +0100 |
From: Christian Borntraeger <address@hidden>
Sometimes (e.g. early boot) a guest is broken in such ways that it loops
100% delivering operation exceptions (illegal operation) but the pgm new
PSW is not set properly. This will result in code being read from
address zero, which usually contains another illegal op. Let's detect
this case and put the guest in crashed state. Instead of only detecting
this for address zero apply a heuristic that will work for any program
check new psw so that it will also reach the crashed state if you
provide some random elf file to the -kernel option.
We do not want guest problem state to be able to trigger a guest panic,
e.g. by faulting on an address that is the same as the program check
new PSW, so we check for the problem state bit being off.
With this we
a: get rid of CPU consumption of such broken guests
b: keep the program old PSW. This allows to find out the original illegal
operation - making debugging such early boot issues much easier than
with single stepping
This relies on the kernel using a similar heuristic and passing such
operation exceptions to user space.
Signed-off-by: Christian Borntraeger <address@hidden>
Signed-off-by: Cornelia Huck <address@hidden>
---
target/s390x/kvm.c | 43 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 25367807f4..5ec050cf89 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1867,6 +1867,40 @@ static void unmanageable_intercept(S390CPU *cpu, const
char *str, int pswoffset)
qemu_system_guest_panicked(NULL);
}
+/* try to detect pgm check loops */
+static int handle_oper_loop(S390CPU *cpu, struct kvm_run *run)
+{
+ CPUState *cs = CPU(cpu);
+ PSW oldpsw, newpsw;
+
+ cpu_synchronize_state(cs);
+ newpsw.mask = ldq_phys(cs->as, cpu->env.psa +
+ offsetof(LowCore, program_new_psw));
+ newpsw.addr = ldq_phys(cs->as, cpu->env.psa +
+ offsetof(LowCore, program_new_psw) + 8);
+ oldpsw.mask = run->psw_mask;
+ oldpsw.addr = run->psw_addr;
+ /*
+ * Avoid endless loops of operation exceptions, if the pgm new
+ * PSW will cause a new operation exception.
+ * The heuristic checks if the pgm new psw is within 6 bytes before
+ * the faulting psw address (with same DAT, AS settings) and the
+ * new psw is not a wait psw and the fault was not triggered by
+ * problem state. In that case go into crashed state.
+ */
+
+ if (oldpsw.addr - newpsw.addr <= 6 &&
+ !(newpsw.mask & PSW_MASK_WAIT) &&
+ !(oldpsw.mask & PSW_MASK_PSTATE) &&
+ (newpsw.mask & PSW_MASK_ASC) == (oldpsw.mask & PSW_MASK_ASC) &&
+ (newpsw.mask & PSW_MASK_DAT) == (oldpsw.mask & PSW_MASK_DAT)) {
+ unmanageable_intercept(cpu, "operation exception loop",
+ offsetof(LowCore, program_new_psw));
+ return EXCP_HALTED;
+ }
+ return 0;
+}
+
static int handle_intercept(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
@@ -1914,11 +1948,14 @@ static int handle_intercept(S390CPU *cpu)
r = EXCP_HALTED;
break;
case ICPT_OPEREXC:
- /* currently only instr 0x0000 after enabled via capability */
+ /* check for break points */
r = handle_sw_breakpoint(cpu, run);
if (r == -ENOENT) {
- enter_pgmcheck(cpu, PGM_OPERATION);
- r = 0;
+ /* Then check for potential pgm check loops */
+ r = handle_oper_loop(cpu, run);
+ if (r == 0) {
+ enter_pgmcheck(cpu, PGM_OPERATION);
+ }
}
break;
case ICPT_SOFT_INTERCEPT:
--
2.11.0
- [Qemu-devel] [PULL 00/13] s390x patches for 2.9, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 01/13] s390x/s390-virtio: get rid of DPRINTF, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 05/13] virtio-ccw: add virtio-crypto-ccw device, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 02/13] s390x/kvm: detect some program check loops,
Cornelia Huck <=
- [Qemu-devel] [PULL 03/13] s390x/flic: fail migration on source already, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 06/13] virtio-ccw: Check the number of vqs in CCW_CMD_SET_IND, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 04/13] virtio-ccw: handle virtio 1 only devices, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 07/13] s390x: add property adapter_routes_max_batch, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 09/13] s390x: bump ADAPTER_ROUTES_MAX_GSI, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 08/13] virtio-ccw: check flic->adapter_routes_max_batch, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 10/13] virtio-ccw: support VIRTIO_QUEUE_MAX virtqueues, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 12/13] s390x/arch_dump: pass cpuid into notes sections, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 13/13] s390x/css: handle format-0 TIC CCW correctly, Cornelia Huck, 2017/02/24
- [Qemu-devel] [PULL 11/13] s390x/arch_dump: use proper note name and note size, Cornelia Huck, 2017/02/24