* [kvm-unit-tests PATCH v2 0/2] s390x: program interrupt handler
@ 2017-05-31 12:39 David Hildenbrand
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 1/2] s390x: generate asm offsets for the lowcore David Hildenbrand
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them David Hildenbrand
0 siblings, 2 replies; 9+ messages in thread
From: David Hildenbrand @ 2017-05-31 12:39 UTC (permalink / raw)
To: kvm
Cc: Paolo Bonzini, Radim Krčmář, Thomas Huth, david,
Christian Borntraeger
Add a program interrupt handler and two simple program interrupt tests.
The check for the ADRESSING exception will fail on
- TCG without "target/s390x: addressing exceptions are suppressing"
- Old KVM versions without 492d8642eaef ("KVM: s390: Forward PSW to next
instruction for addressing exceptions")
v1 -> v2: (s390x: generate asm offsets for the lowcore)
- Added missing field (mcck extended save area)
- Dropped alignment attribute for naturally aligned struct
v1 -> v2: (pgm interrupt handler and a way to test them)
- Renamed everything from irq->int/interrupt to keep it consistent
- Use global lowcore variable struct lowcore *lc;
- Safe+restore fpr and fpc in interrupt handler
- Setup pgm int handler using mvc instruction
- Renamed received_pgm_irq to check_pgm_int_code() and moved "report"
into "check_pgm_int_code()"
- Minor style + comment fixes
David Hildenbrand (2):
s390x: generate asm offsets for the lowcore
s390x: pgm interrupt handler and a way to test them
lib/s390x/asm-offsets.c | 74 ++++++++++++++++++++++
lib/s390x/asm/arch_def.h | 146 ++++++++++++++++++++++++++++++++++++++++++++
lib/s390x/asm/asm-offsets.h | 10 +++
lib/s390x/asm/interrupt.h | 18 ++++++
lib/s390x/interrupt.c | 82 +++++++++++++++++++++++++
s390x/Makefile | 10 ++-
s390x/cstart64.S | 55 +++++++++++++++++
s390x/selftest.c | 13 ++++
8 files changed, 407 insertions(+), 1 deletion(-)
create mode 100644 lib/s390x/asm-offsets.c
create mode 100644 lib/s390x/asm/arch_def.h
create mode 100644 lib/s390x/asm/asm-offsets.h
create mode 100644 lib/s390x/asm/interrupt.h
create mode 100644 lib/s390x/interrupt.c
--
2.9.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [kvm-unit-tests PATCH v2 1/2] s390x: generate asm offsets for the lowcore
2017-05-31 12:39 [kvm-unit-tests PATCH v2 0/2] s390x: program interrupt handler David Hildenbrand
@ 2017-05-31 12:39 ` David Hildenbrand
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them David Hildenbrand
1 sibling, 0 replies; 9+ messages in thread
From: David Hildenbrand @ 2017-05-31 12:39 UTC (permalink / raw)
To: kvm
Cc: Paolo Bonzini, Radim Krčmář, Thomas Huth, david,
Christian Borntraeger
Add the s390x psw and lowcore structs and generate asm offsets for lowcore
fields. Add all lowcore fields defined in the current PoP (z13).
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
lib/s390x/asm-offsets.c | 71 ++++++++++++++++++++++++++++++++++++
lib/s390x/asm/arch_def.h | 87 +++++++++++++++++++++++++++++++++++++++++++++
lib/s390x/asm/asm-offsets.h | 10 ++++++
s390x/Makefile | 8 ++++-
4 files changed, 175 insertions(+), 1 deletion(-)
create mode 100644 lib/s390x/asm-offsets.c
create mode 100644 lib/s390x/asm/arch_def.h
create mode 100644 lib/s390x/asm/asm-offsets.h
diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
new file mode 100644
index 0000000..1e8d5ce
--- /dev/null
+++ b/lib/s390x/asm-offsets.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <libcflat.h>
+#include <kbuild.h>
+#include <asm/arch_def.h>
+
+int main(void)
+{
+ OFFSET(GEN_LC_EXT_INT_PARAM, lowcore, ext_int_param);
+ OFFSET(GEN_LC_CPU_ADDR, lowcore, cpu_addr);
+ OFFSET(GEN_LC_EXT_INT_CODE, lowcore, ext_int_code);
+ OFFSET(GEN_LC_SVC_INT_ID, lowcore, svc_int_id);
+ OFFSET(GEN_LC_SVC_INT_CODE, lowcore, svc_int_code);
+ OFFSET(GEN_LC_PGM_INT_ID, lowcore, pgm_int_id);
+ OFFSET(GEN_LC_PGM_INT_CODE, lowcore, pgm_int_code);
+ OFFSET(GEN_LC_DXC_VXC, lowcore, dxc_vxc);
+ OFFSET(GEN_LC_MON_CLASS_NB, lowcore, mon_class_nb);
+ OFFSET(GEN_LC_PER_CODE, lowcore, per_code);
+ OFFSET(GEN_LC_PER_ATMID, lowcore, per_atmid);
+ OFFSET(GEN_LC_PER_ADDR, lowcore, per_addr);
+ OFFSET(GEN_LC_EXC_ACC_ID, lowcore, exc_acc_id);
+ OFFSET(GEN_LC_PER_ACC_ID, lowcore, per_acc_id);
+ OFFSET(GEN_LC_OP_ACC_ID, lowcore, op_acc_id);
+ OFFSET(GEN_LC_ARCH_MODE_ID, lowcore, arch_mode_id);
+ OFFSET(GEN_LC_TRANS_EXC_ID, lowcore, trans_exc_id);
+ OFFSET(GEN_LC_MON_CODE, lowcore, mon_code);
+ OFFSET(GEN_LC_SUBSYS_ID_WORD, lowcore, subsys_id_word);
+ OFFSET(GEN_LC_IO_INT_PARAM, lowcore, io_int_param);
+ OFFSET(GEN_LC_IO_INT_WORD, lowcore, io_int_word);
+ OFFSET(GEN_LC_STFL, lowcore, stfl);
+ OFFSET(GEN_LC_MCCK_INT_CODE, lowcore, mcck_int_code);
+ OFFSET(GEN_LC_EXT_DAMAGE_CODE, lowcore, ext_damage_code);
+ OFFSET(GEN_LC_FAILING_STORAGE_ADDR, lowcore, failing_storage_addr);
+ OFFSET(GEN_LC_EMON_CA_ORIGIN, lowcore, emon_ca_origin);
+ OFFSET(GEN_LC_EMON_CA_SIZE, lowcore, emon_ca_size);
+ OFFSET(GEN_LC_EMON_EXC_COUNT, lowcore, emon_exc_count);
+ OFFSET(GEN_LC_BREAKING_EVENT_ADDR, lowcore, breaking_event_addr);
+ OFFSET(GEN_LC_RESTART_OLD_PSW, lowcore, restart_old_psw);
+ OFFSET(GEN_LC_EXT_OLD_PSW, lowcore, ext_old_psw);
+ OFFSET(GEN_LC_SVC_OLD_PSW, lowcore, svc_old_psw);
+ OFFSET(GEN_LC_PGM_OLD_PSW, lowcore, pgm_old_psw);
+ OFFSET(GEN_LC_MCCK_OLD_PSW, lowcore, mcck_old_psw);
+ OFFSET(GEN_LC_IO_OLD_PSW, lowcore, io_old_psw);
+ OFFSET(GEN_LC_RESTART_NEW_PSW, lowcore, restart_new_psw);
+ OFFSET(GEN_LC_EXT_NEW_PSW, lowcore, ext_new_psw);
+ OFFSET(GEN_LC_SVC_NEW_PSW, lowcore, svc_new_psw);
+ OFFSET(GEN_LC_PGM_NEW_PSW, lowcore, pgm_new_psw);
+ OFFSET(GEN_LC_MCCK_NEW_PSW, lowcore, mcck_new_psw);
+ OFFSET(GEN_LC_IO_NEW_PSW, lowcore, io_new_psw);
+ OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
+ OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
+ OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
+ OFFSET(GEN_LC_PSW_SA, lowcore, psw_sa);
+ OFFSET(GEN_LC_PREFIX_SA, lowcore, prefix_sa);
+ OFFSET(GEN_LC_FPC_SA, lowcore, fpc_sa);
+ OFFSET(GEN_LC_TOD_PR_SA, lowcore, tod_pr_sa);
+ OFFSET(GEN_LC_CPUTM_SA, lowcore, cputm_sa);
+ OFFSET(GEN_LC_CC_SA, lowcore, cc_sa);
+ OFFSET(GEN_LC_ARS_SA, lowcore, ars_sa);
+ OFFSET(GEN_LC_CRS_SA, lowcore, crs_sa);
+ OFFSET(GEN_LC_PGM_INT_TDB, lowcore, pgm_int_tdb);
+
+ return 0;
+}
diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
new file mode 100644
index 0000000..efa7f12
--- /dev/null
+++ b/lib/s390x/asm/arch_def.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#ifndef _ASM_S390X_ARCH_DEF_H_
+#define _ASM_S390X_ARCH_DEF_H_
+
+struct psw {
+ uint64_t mask;
+ uint64_t addr;
+};
+
+struct lowcore {
+ uint8_t pad_0x0000[0x0080 - 0x0000]; /* 0x0000 */
+ uint32_t ext_int_param; /* 0x0080 */
+ uint16_t cpu_addr; /* 0x0084 */
+ uint16_t ext_int_code; /* 0x0086 */
+ uint16_t svc_int_id; /* 0x0088 */
+ uint16_t svc_int_code; /* 0x008a */
+ uint16_t pgm_int_id; /* 0x008c */
+ uint16_t pgm_int_code; /* 0x008e */
+ uint32_t dxc_vxc; /* 0x0090 */
+ uint16_t mon_class_nb; /* 0x0094 */
+ uint8_t per_code; /* 0x0096 */
+ uint8_t per_atmid; /* 0x0097 */
+ uint64_t per_addr; /* 0x0098 */
+ uint8_t exc_acc_id; /* 0x00a0 */
+ uint8_t per_acc_id; /* 0x00a1 */
+ uint8_t op_acc_id; /* 0x00a2 */
+ uint8_t arch_mode_id; /* 0x00a3 */
+ uint8_t pad_0x00a4[0x00a8 - 0x00a4]; /* 0x00a4 */
+ uint64_t trans_exc_id; /* 0x00a8 */
+ uint64_t mon_code; /* 0x00b0 */
+ uint32_t subsys_id_word; /* 0x00b8 */
+ uint32_t io_int_param; /* 0x00bc */
+ uint32_t io_int_word; /* 0x00c0 */
+ uint8_t pad_0x00c4[0x00c8 - 0x00c4]; /* 0x00c4 */
+ uint32_t stfl; /* 0x00c8 */
+ uint8_t pad_0x00cc[0x00e8 - 0x00cc]; /* 0x00cc */
+ uint64_t mcck_int_code; /* 0x00e8 */
+ uint8_t pad_0x00f0[0x00f4 - 0x00f0]; /* 0x00f0 */
+ uint32_t ext_damage_code; /* 0x00f4 */
+ uint64_t failing_storage_addr; /* 0x00f8 */
+ uint64_t emon_ca_origin; /* 0x0100 */
+ uint32_t emon_ca_size; /* 0x0108 */
+ uint32_t emon_exc_count; /* 0x010c */
+ uint64_t breaking_event_addr; /* 0x0110 */
+ uint8_t pad_0x0118[0x0120 - 0x0118]; /* 0x0118 */
+ struct psw restart_old_psw; /* 0x0120 */
+ struct psw ext_old_psw; /* 0x0130 */
+ struct psw svc_old_psw; /* 0x0140 */
+ struct psw pgm_old_psw; /* 0x0150 */
+ struct psw mcck_old_psw; /* 0x0160 */
+ struct psw io_old_psw; /* 0x0170 */
+ uint8_t pad_0x0180[0x01a0 - 0x0180]; /* 0x0180 */
+ struct psw restart_new_psw; /* 0x01a0 */
+ struct psw ext_new_psw; /* 0x01b0 */
+ struct psw svc_new_psw; /* 0x01c0 */
+ struct psw pgm_new_psw; /* 0x01d0 */
+ struct psw mcck_new_psw; /* 0x01e0 */
+ struct psw io_new_psw; /* 0x01f0 */
+ uint8_t pad_0x0200[0x11b0 - 0x0200]; /* 0x0200 */
+ uint64_t mcck_ext_sa_addr; /* 0x11b0 */
+ uint8_t pad_0x11b8[0x1200 - 0x11b8]; /* 0x11b8 */
+ uint64_t fprs_sa[16]; /* 0x1200 */
+ uint64_t grs_sa[16]; /* 0x1280 */
+ struct psw psw_sa; /* 0x1300 */
+ uint8_t pad_0x1310[0x1318 - 0x1310]; /* 0x1310 */
+ uint32_t prefix_sa; /* 0x1318 */
+ uint32_t fpc_sa; /* 0x131c */
+ uint8_t pad_0x1320[0x1324 - 0x1320]; /* 0x1320 */
+ uint32_t tod_pr_sa; /* 0x1324 */
+ uint64_t cputm_sa; /* 0x1328 */
+ uint64_t cc_sa; /* 0x1330 */
+ uint8_t pad_0x1338[0x1340 - 0x1338]; /* 0x1338 */
+ uint32_t ars_sa[16]; /* 0x1340 */
+ uint64_t crs_sa[16]; /* 0x1380 */
+ uint8_t pad_0x1400[0x1800 - 0x1400]; /* 0x1400 */
+ uint8_t pgm_int_tdb[0x1900 - 0x1800]; /* 0x1800 */
+} __attribute__ ((__packed__));
+
+#endif
diff --git a/lib/s390x/asm/asm-offsets.h b/lib/s390x/asm/asm-offsets.h
new file mode 100644
index 0000000..a6d7af8
--- /dev/null
+++ b/lib/s390x/asm/asm-offsets.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <generated/asm-offsets.h>
diff --git a/s390x/Makefile b/s390x/Makefile
index e80add0..4e4b94a 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -15,6 +15,9 @@ LDFLAGS += -nostdlib
# We want to keep intermediate files
.PRECIOUS: %.o
+asm-offsets = lib/$(ARCH)/asm-offsets.h
+include $(SRCDIR)/scripts/asm-offsets.mak
+
cflatobjs += lib/util.o
cflatobjs += lib/alloc.o
cflatobjs += lib/s390x/io.o
@@ -33,5 +36,8 @@ FLATLIBS = $(libcflat)
$(filter %.o, $^) $(FLATLIBS) $(@:.elf=.aux.o)
$(RM) $(@:.elf=.aux.o)
-arch_clean:
+arch_clean: asm_offsets_clean
$(RM) $(TEST_DIR)/*.{o,elf} $(TEST_DIR)/.*.d lib/s390x/.*.d
+
+generated-files = $(asm-offsets)
+$(test_cases:.elf=.o) $(cstart.o) $(cflatobjs): $(generated-files)
--
2.9.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them
2017-05-31 12:39 [kvm-unit-tests PATCH v2 0/2] s390x: program interrupt handler David Hildenbrand
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 1/2] s390x: generate asm offsets for the lowcore David Hildenbrand
@ 2017-05-31 12:39 ` David Hildenbrand
2017-05-31 12:51 ` Paolo Bonzini
2017-05-31 13:22 ` Thomas Huth
1 sibling, 2 replies; 9+ messages in thread
From: David Hildenbrand @ 2017-05-31 12:39 UTC (permalink / raw)
To: kvm
Cc: Paolo Bonzini, Radim Krčmář, Thomas Huth, david,
Christian Borntraeger
The program interrupt handler will detect unexpected program interrupts and
allow to expect + verify program interrupts for testing purposes.
We need "-fno-delete-null-pointer-checks", otherwise trying to access the
lowcore at address 0 makes GCC generate very weird code.
Add two tests to test for simple operation and addressing exceptions.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
lib/s390x/asm-offsets.c | 3 ++
lib/s390x/asm/arch_def.h | 61 ++++++++++++++++++++++++++++++++++-
lib/s390x/asm/interrupt.h | 18 +++++++++++
lib/s390x/interrupt.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++
s390x/Makefile | 2 ++
s390x/cstart64.S | 55 +++++++++++++++++++++++++++++++
s390x/selftest.c | 13 ++++++++
7 files changed, 233 insertions(+), 1 deletion(-)
create mode 100644 lib/s390x/asm/interrupt.h
create mode 100644 lib/s390x/interrupt.c
diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
index 1e8d5ce..f1012c6 100644
--- a/lib/s390x/asm-offsets.c
+++ b/lib/s390x/asm-offsets.c
@@ -54,6 +54,9 @@ int main(void)
OFFSET(GEN_LC_PGM_NEW_PSW, lowcore, pgm_new_psw);
OFFSET(GEN_LC_MCCK_NEW_PSW, lowcore, mcck_new_psw);
OFFSET(GEN_LC_IO_NEW_PSW, lowcore, io_new_psw);
+ OFFSET(GEN_LC_SW_INT_GRS, lowcore, sw_int_grs);
+ OFFSET(GEN_LC_SW_INT_FPRS, lowcore, sw_int_fprs);
+ OFFSET(GEN_LC_SW_INT_FPC, lowcore, sw_int_fpc);
OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
index efa7f12..07d467e 100644
--- a/lib/s390x/asm/arch_def.h
+++ b/lib/s390x/asm/arch_def.h
@@ -64,7 +64,11 @@ struct lowcore {
struct psw pgm_new_psw; /* 0x01d0 */
struct psw mcck_new_psw; /* 0x01e0 */
struct psw io_new_psw; /* 0x01f0 */
- uint8_t pad_0x0200[0x11b0 - 0x0200]; /* 0x0200 */
+ /* sw definition: save area for registers in interrupt handlers */
+ uint64_t sw_int_grs[16]; /* 0x0200 */
+ uint64_t sw_int_fprs[16]; /* 0x0280 */
+ uint32_t sw_int_fpc; /* 0x0300 */
+ uint8_t pad_0x0304[0x11b0 - 0x0304]; /* 0x0304 */
uint64_t mcck_ext_sa_addr; /* 0x11b0 */
uint8_t pad_0x11b8[0x1200 - 0x11b8]; /* 0x11b8 */
uint64_t fprs_sa[16]; /* 0x1200 */
@@ -84,4 +88,59 @@ struct lowcore {
uint8_t pgm_int_tdb[0x1900 - 0x1800]; /* 0x1800 */
} __attribute__ ((__packed__));
+#define PGM_INT_CODE_OPERATION 0x01
+#define PGM_INT_CODE_PRIVILEGED_OPERATION 0x02
+#define PGM_INT_CODE_EXECUTE 0x03
+#define PGM_INT_CODE_PROTECTION 0x04
+#define PGM_INT_CODE_ADDRESSING 0x05
+#define PGM_INT_CODE_SPECIFICATION 0x06
+#define PGM_INT_CODE_DATA 0x07
+#define PGM_INT_CODE_FIXED_POINT_OVERFLOW 0x08
+#define PGM_INT_CODE_FIXED_POINT_DIVIDE 0x09
+#define PGM_INT_CODE_DECIMAL_OVERFLOW 0x0a
+#define PGM_INT_CODE_DECIMAL_DIVIDE 0x0b
+#define PGM_INT_CODE_HFP_EXPONENT_OVERFLOW 0x0c
+#define PGM_INT_CODE_HFP_EXPONENT_UNDERFLOW 0x0d
+#define PGM_INT_CODE_HFP_SIGNIFICANCE 0x0e
+#define PGM_INT_CODE_HFP_DIVIDE 0x0f
+#define PGM_INT_CODE_SEGMENT_TRANSLATION 0x10
+#define PGM_INT_CODE_PAGE_TRANSLATION 0x11
+#define PGM_INT_CODE_TRANSLATION_SPEC 0x12
+#define PGM_INT_CODE_SPECIAL_OPERATION 0x13
+#define PGM_INT_CODE_OPERAND 0x15
+#define PGM_INT_CODE_TRACE_TABLE 0x16
+#define PGM_INT_CODE_VECTOR_PROCESSING 0x1b
+#define PGM_INT_CODE_SPACE_SWITCH_EVENT 0x1c
+#define PGM_INT_CODE_HFP_SQUARE_ROOT 0x1d
+#define PGM_INT_CODE_PC_TRANSLATION_SPEC 0x1f
+#define PGM_INT_CODE_AFX_TRANSLATION 0x20
+#define PGM_INT_CODE_ASX_TRANSLATION 0x21
+#define PGM_INT_CODE_LX_TRANSLATION 0x22
+#define PGM_INT_CODE_EX_TRANSLATION 0x23
+#define PGM_INT_CODE_PRIMARY_AUTHORITY 0x24
+#define PGM_INT_CODE_SECONDARY_AUTHORITY 0x25
+#define PGM_INT_CODE_LFX_TRANSLATION 0x26
+#define PGM_INT_CODE_LSX_TRANSLATION 0x27
+#define PGM_INT_CODE_ALET_SPECIFICATION 0x28
+#define PGM_INT_CODE_ALEN_TRANSLATION 0x29
+#define PGM_INT_CODE_ALE_SEQUENCE 0x2a
+#define PGM_INT_CODE_ASTE_VALIDITY 0x2b
+#define PGM_INT_CODE_ASTE_SEQUENCE 0x2c
+#define PGM_INT_CODE_EXTENDED_AUTHORITY 0x2d
+#define PGM_INT_CODE_LSTE_SEQUENCE 0x2e
+#define PGM_INT_CODE_ASTE_INSTANCE 0x2f
+#define PGM_INT_CODE_STACK_FULL 0x30
+#define PGM_INT_CODE_STACK_EMPTY 0x31
+#define PGM_INT_CODE_STACK_SPECIFICATION 0x32
+#define PGM_INT_CODE_STACK_TYPE 0x33
+#define PGM_INT_CODE_STACK_OPERATION 0x34
+#define PGM_INT_CODE_ASCE_TYPE 0x38
+#define PGM_INT_CODE_REGION_FIRST_TRANS 0x39
+#define PGM_INT_CODE_REGION_SECOND_TRANS 0x3a
+#define PGM_INT_CODE_REGION_THIRD_TRANS 0x3b
+#define PGM_INT_CODE_MONITOR_EVENT 0x40
+#define PGM_INT_CODE_PER 0x80
+#define PGM_INT_CODE_CRYPTO_OPERATION 0x119
+#define PGM_INT_CODE_TX_ABORTED_EVENT 0x200
+
#endif
diff --git a/lib/s390x/asm/interrupt.h b/lib/s390x/asm/interrupt.h
new file mode 100644
index 0000000..383d312
--- /dev/null
+++ b/lib/s390x/asm/interrupt.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#ifndef _ASMS390X_IRQ_H_
+#define _ASMS390X_IRQ_H_
+#include <asm/arch_def.h>
+
+void handle_pgm_int(void);
+void expect_pgm_int(void);
+void check_pgm_int_code(uint16_t code);
+
+#endif
diff --git a/lib/s390x/interrupt.c b/lib/s390x/interrupt.c
new file mode 100644
index 0000000..8d861a2
--- /dev/null
+++ b/lib/s390x/interrupt.c
@@ -0,0 +1,82 @@
+/*
+ * s390x interrupt handling
+ *
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <libcflat.h>
+#include <asm/interrupt.h>
+#include <asm/barrier.h>
+
+static bool pgm_int_expected;
+static struct lowcore *lc;
+
+void expect_pgm_int(void)
+{
+ pgm_int_expected = true;
+ lc->pgm_int_code = 0;
+ mb();
+}
+
+void check_pgm_int_code(uint16_t code)
+{
+ mb();
+ report("Program interrupt: expected(%d) == received(%d)",
+ code == lc->pgm_int_code, code, lc->pgm_int_code);
+}
+
+static void fixup_pgm_int(void)
+{
+ switch (lc->pgm_int_code) {
+ case PGM_INT_CODE_SEGMENT_TRANSLATION:
+ case PGM_INT_CODE_PAGE_TRANSLATION:
+ case PGM_INT_CODE_TRACE_TABLE:
+ case PGM_INT_CODE_AFX_TRANSLATION:
+ case PGM_INT_CODE_ASX_TRANSLATION:
+ case PGM_INT_CODE_LX_TRANSLATION:
+ case PGM_INT_CODE_EX_TRANSLATION:
+ case PGM_INT_CODE_PRIMARY_AUTHORITY:
+ case PGM_INT_CODE_SECONDARY_AUTHORITY:
+ case PGM_INT_CODE_LFX_TRANSLATION:
+ case PGM_INT_CODE_LSX_TRANSLATION:
+ case PGM_INT_CODE_ALEN_TRANSLATION:
+ case PGM_INT_CODE_ALE_SEQUENCE:
+ case PGM_INT_CODE_ASTE_VALIDITY:
+ case PGM_INT_CODE_ASTE_SEQUENCE:
+ case PGM_INT_CODE_EXTENDED_AUTHORITY:
+ case PGM_INT_CODE_LSTE_SEQUENCE:
+ case PGM_INT_CODE_ASTE_INSTANCE:
+ case PGM_INT_CODE_STACK_FULL:
+ case PGM_INT_CODE_STACK_EMPTY:
+ case PGM_INT_CODE_STACK_SPECIFICATION:
+ case PGM_INT_CODE_STACK_TYPE:
+ case PGM_INT_CODE_STACK_OPERATION:
+ case PGM_INT_CODE_ASCE_TYPE:
+ case PGM_INT_CODE_REGION_FIRST_TRANS:
+ case PGM_INT_CODE_REGION_SECOND_TRANS:
+ case PGM_INT_CODE_REGION_THIRD_TRANS:
+ case PGM_INT_CODE_PER:
+ case PGM_INT_CODE_CRYPTO_OPERATION:
+ /* The interrupt was nullified, the old PSW points at the
+ * responsible instruction. Forward the PSW so we don't loop.
+ */
+ lc->pgm_old_psw.addr += lc->pgm_int_id;
+ }
+ /* suppressed/terminated/completed point already at the next address */
+}
+
+void handle_pgm_int(void)
+{
+ if (!pgm_int_expected)
+ report_abort("Unexpected program interrupt: %d at %#lx, ilen %d\n",
+ lc->pgm_int_code, lc->pgm_old_psw.addr,
+ lc->pgm_int_id);
+
+ pgm_int_expected = false;
+ fixup_pgm_int();
+}
diff --git a/s390x/Makefile b/s390x/Makefile
index 4e4b94a..b48f8ab 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -10,6 +10,7 @@ CFLAGS += -Wextra
CFLAGS += -I $(SRCDIR)/lib
CFLAGS += -O2
CFLAGS += -march=z900
+CFLAGS += -fno-delete-null-pointer-checks
LDFLAGS += -nostdlib
# We want to keep intermediate files
@@ -23,6 +24,7 @@ cflatobjs += lib/alloc.o
cflatobjs += lib/s390x/io.o
cflatobjs += lib/s390x/stack.o
cflatobjs += lib/s390x/sclp-ascii.o
+cflatobjs += lib/s390x/interrupt.o
OBJDIRS += lib/s390x
diff --git a/s390x/cstart64.S b/s390x/cstart64.S
index 28cd59d..4d0c877 100644
--- a/s390x/cstart64.S
+++ b/s390x/cstart64.S
@@ -10,6 +10,8 @@
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License version 2.
*/
+#include <asm/asm-offsets.h>
+
.section .init
/* entry point - for KVM + TCG we directly start in 64 bit mode */
@@ -21,6 +23,10 @@ start:
larl %r1, initital_psw
lpswe 0(%r1)
init_psw_cont:
+ /* setup pgm interrupt handler */
+ larl %r1, pgm_int_psw
+ mvc GEN_LC_PGM_NEW_PSW(16), 0(%r1)
+ /* setup cr0, enabling e.g. AFP-register control */
larl %r1, initital_cr0
lctlg %c0, %c0, 0(%r1)
/* call setup() */
@@ -36,9 +42,58 @@ init_psw_cont:
/* call exit() */
j exit
+pgm_int:
+ /* save grs 0-15 */
+ stmg %r0, %r15, GEN_LC_SW_INT_GRS
+ /* save fprs 0-15 + fpc */
+ larl %r1, GEN_LC_SW_INT_FPRS
+ std %f0, 0(%r1)
+ std %f1, 8(%r1)
+ std %f2, 16(%r1)
+ std %f3, 24(%r1)
+ std %f4, 32(%r1)
+ std %f5, 40(%r1)
+ std %f6, 48(%r1)
+ std %f7, 56(%r1)
+ std %f8, 64(%r1)
+ std %f9, 72(%r1)
+ std %f10, 80(%r1)
+ std %f11, 88(%r1)
+ std %f12, 96(%r1)
+ std %f13, 104(%r1)
+ std %f14, 112(%r1)
+ std %f15, 120(%r1)
+ stfpc GEN_LC_SW_INT_FPC
+ /* call our c handler */
+ brasl %r14, handle_pgm_int
+ /* restore fprs 0-15 + fpc */
+ larl %r1, GEN_LC_SW_INT_FPRS
+ ld %f0, 0(%r1)
+ ld %f1, 8(%r1)
+ ld %f2, 16(%r1)
+ ld %f3, 24(%r1)
+ ld %f4, 32(%r1)
+ ld %f5, 40(%r1)
+ ld %f6, 48(%r1)
+ ld %f7, 56(%r1)
+ ld %f8, 64(%r1)
+ ld %f9, 72(%r1)
+ ld %f10, 80(%r1)
+ ld %f11, 88(%r1)
+ ld %f12, 96(%r1)
+ ld %f13, 104(%r1)
+ ld %f14, 112(%r1)
+ ld %f15, 120(%r1)
+ lfpc GEN_LC_SW_INT_FPC
+ /* restore grs 0-15 */
+ lmg %r0, %r15, GEN_LC_SW_INT_GRS
+ lpswe GEN_LC_PGM_OLD_PSW
+
.align 8
initital_psw:
.quad 0x0000000180000000, init_psw_cont
+pgm_int_psw:
+ .quad 0x0000000180000000, pgm_int
initital_cr0:
/* enable AFP-register control, so FP regs (+BFP instr) can be used */
.quad 0x0000000000040000
diff --git a/s390x/selftest.c b/s390x/selftest.c
index 4558e47..ca94158 100644
--- a/s390x/selftest.c
+++ b/s390x/selftest.c
@@ -10,6 +10,7 @@
*/
#include <libcflat.h>
#include <util.h>
+#include <asm/interrupt.h>
static void test_fp(void)
{
@@ -25,6 +26,17 @@ static void test_fp(void)
report("3.0/2.0 == 1.5", c == 1.5);
}
+static void test_pgm_int(void)
+{
+ expect_pgm_int();
+ asm volatile(" .insn e,0x0001"); /* used for SW breakpoints in QEMU */
+ check_pgm_int_code(PGM_INT_CODE_OPERATION);
+
+ expect_pgm_int();
+ *((unsigned int*)-1) = 1;
+ check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
+}
+
int main(int argc, char**argv)
{
report_prefix_push("selftest");
@@ -36,6 +48,7 @@ int main(int argc, char**argv)
report("argv[2] == 123", !strcmp(argv[2], "123"));
test_fp();
+ test_pgm_int();
return report_summary();
}
--
2.9.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them David Hildenbrand
@ 2017-05-31 12:51 ` Paolo Bonzini
2017-05-31 13:25 ` Thomas Huth
2017-05-31 13:26 ` David Hildenbrand
2017-05-31 13:22 ` Thomas Huth
1 sibling, 2 replies; 9+ messages in thread
From: Paolo Bonzini @ 2017-05-31 12:51 UTC (permalink / raw)
To: David Hildenbrand, kvm
Cc: Radim Krčmář, Thomas Huth, Christian Borntraeger
On 31/05/2017 14:39, David Hildenbrand wrote:
> + expect_pgm_int();
> + *((unsigned int*)-1) = 1;
> + check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
QEMU gets
ABORT: selftest: Unexpected program interrupt: 5 at 0x12b4c, ilen 4
It seems that QEMU doesn't point the PSW at the next instruction:
IN: main
0x0000000000012b44: lghi %r1,-1
0x0000000000012b48: lhi %r3,1
0x0000000000012b4c: st %r3,0(%r1)
0x0000000000012b50: lghi %r2,5
0x0000000000012b54: brasl %r14,0x128e8
0x0000000000012b4c: st %r3,0(%r1)
0x0000000000012b50: lghi %r2,5
0x0000000000012b54: brasl %r14,0x128e8 # this is expect_pgm_int
Trace 0x7f5ff6c7f520 [0: 0000000000012b44] main
Trace 0x7f5ff6c7bc20 [0: 000000000001004e]
Trace 0x7f5ff6c7c960 [0: 0000000000012918] handle_pgm_int
Trace 0x7f5ff6c7d280 [0: 00000000000100a4]
and now it gets another program interrupt:
IN: main
0x0000000000012b4c: st %r3,0(%r1)
0x0000000000012b50: lghi %r2,5
0x0000000000012b54: brasl %r14,0x128e8
Trace 0x7f5ff6c7f600 [0: 0000000000012b4c] main
Trace 0x7f5ff6c7bc20 [0: 000000000001004e]
Trace 0x7f5ff6c7c960 [0: 0000000000012918] handle_pgm_int
Thanks,
Paolo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them David Hildenbrand
2017-05-31 12:51 ` Paolo Bonzini
@ 2017-05-31 13:22 ` Thomas Huth
2017-05-31 13:30 ` David Hildenbrand
1 sibling, 1 reply; 9+ messages in thread
From: Thomas Huth @ 2017-05-31 13:22 UTC (permalink / raw)
To: David Hildenbrand, kvm
Cc: Paolo Bonzini, Radim Krčmář, Christian Borntraeger
On 31.05.2017 14:39, David Hildenbrand wrote:
> The program interrupt handler will detect unexpected program interrupts and
> allow to expect + verify program interrupts for testing purposes.
>
> We need "-fno-delete-null-pointer-checks", otherwise trying to access the
> lowcore at address 0 makes GCC generate very weird code.
>
> Add two tests to test for simple operation and addressing exceptions.
>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
[...]
> diff --git a/lib/s390x/interrupt.c b/lib/s390x/interrupt.c
> new file mode 100644
> index 0000000..8d861a2
> --- /dev/null
> +++ b/lib/s390x/interrupt.c
> @@ -0,0 +1,82 @@
> +/*
> + * s390x interrupt handling
> + *
> + * Copyright (c) 2017 Red Hat Inc
> + *
> + * Authors:
> + * David Hildenbrand <david@redhat.com>
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Library General Public License version 2.
> + */
> +#include <libcflat.h>
> +#include <asm/interrupt.h>
> +#include <asm/barrier.h>
> +
> +static bool pgm_int_expected;
> +static struct lowcore *lc;
Cosmetic suggestion:
Maybe make it "static struct lowcore const *lc = 0" to be more explicit?
Apart from that, patch looks fine to me now, so with or without that change:
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them
2017-05-31 12:51 ` Paolo Bonzini
@ 2017-05-31 13:25 ` Thomas Huth
2017-05-31 14:23 ` Paolo Bonzini
2017-05-31 13:26 ` David Hildenbrand
1 sibling, 1 reply; 9+ messages in thread
From: Thomas Huth @ 2017-05-31 13:25 UTC (permalink / raw)
To: Paolo Bonzini, David Hildenbrand, kvm
Cc: Radim Krčmář, Christian Borntraeger
On 31.05.2017 14:51, Paolo Bonzini wrote:
>
>
> On 31/05/2017 14:39, David Hildenbrand wrote:
>> + expect_pgm_int();
>> + *((unsigned int*)-1) = 1;
>> + check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
>
> QEMU gets
>
> ABORT: selftest: Unexpected program interrupt: 5 at 0x12b4c, ilen 4
>
> It seems that QEMU doesn't point the PSW at the next instruction
David mentioned it in the cover letter ... you likely need this patch
here first:
http://patchwork.ozlabs.org/patch/768173/
Thomas
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them
2017-05-31 12:51 ` Paolo Bonzini
2017-05-31 13:25 ` Thomas Huth
@ 2017-05-31 13:26 ` David Hildenbrand
1 sibling, 0 replies; 9+ messages in thread
From: David Hildenbrand @ 2017-05-31 13:26 UTC (permalink / raw)
To: Paolo Bonzini, kvm
Cc: Radim Krčmář, Thomas Huth, Christian Borntraeger
On 31.05.2017 14:51, Paolo Bonzini wrote:
>
>
> On 31/05/2017 14:39, David Hildenbrand wrote:
>> + expect_pgm_int();
>> + *((unsigned int*)-1) = 1;
>> + check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
>
> QEMU gets
>
> ABORT: selftest: Unexpected program interrupt: 5 at 0x12b4c, ilen 4
>
> It seems that QEMU doesn't point the PSW at the next instruction:
>
> IN: main
> 0x0000000000012b44: lghi %r1,-1
> 0x0000000000012b48: lhi %r3,1
> 0x0000000000012b4c: st %r3,0(%r1)
> 0x0000000000012b50: lghi %r2,5
> 0x0000000000012b54: brasl %r14,0x128e8
> 0x0000000000012b4c: st %r3,0(%r1)
> 0x0000000000012b50: lghi %r2,5
> 0x0000000000012b54: brasl %r14,0x128e8 # this is expect_pgm_int
>
> Trace 0x7f5ff6c7f520 [0: 0000000000012b44] main
> Trace 0x7f5ff6c7bc20 [0: 000000000001004e]
> Trace 0x7f5ff6c7c960 [0: 0000000000012918] handle_pgm_int
> Trace 0x7f5ff6c7d280 [0: 00000000000100a4]
>
> and now it gets another program interrupt:
Exactly, the emulator doesn't properly forward the PSW.
>
> IN: main
> 0x0000000000012b4c: st %r3,0(%r1)
> 0x0000000000012b50: lghi %r2,5
> 0x0000000000012b54: brasl %r14,0x128e8
>
> Trace 0x7f5ff6c7f600 [0: 0000000000012b4c] main
> Trace 0x7f5ff6c7bc20 [0: 000000000001004e]
> Trace 0x7f5ff6c7c960 [0: 0000000000012918] handle_pgm_int
>
> Thanks,
>
> Paolo
>
Yes, known problem as described in the cover letter. Happens with
current TCG and old KVM. Patch for TCG is on the list.
Thanks for testing!
--
Thanks,
David
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them
2017-05-31 13:22 ` Thomas Huth
@ 2017-05-31 13:30 ` David Hildenbrand
0 siblings, 0 replies; 9+ messages in thread
From: David Hildenbrand @ 2017-05-31 13:30 UTC (permalink / raw)
To: Thomas Huth, kvm
Cc: Paolo Bonzini, Radim Krčmář, Christian Borntraeger
On 31.05.2017 15:22, Thomas Huth wrote:
> On 31.05.2017 14:39, David Hildenbrand wrote:
>> The program interrupt handler will detect unexpected program interrupts and
>> allow to expect + verify program interrupts for testing purposes.
>>
>> We need "-fno-delete-null-pointer-checks", otherwise trying to access the
>> lowcore at address 0 makes GCC generate very weird code.
>>
>> Add two tests to test for simple operation and addressing exceptions.
>>
>> Signed-off-by: David Hildenbrand <david@redhat.com>
>> ---
> [...]
>> diff --git a/lib/s390x/interrupt.c b/lib/s390x/interrupt.c
>> new file mode 100644
>> index 0000000..8d861a2
>> --- /dev/null
>> +++ b/lib/s390x/interrupt.c
>> @@ -0,0 +1,82 @@
>> +/*
>> + * s390x interrupt handling
>> + *
>> + * Copyright (c) 2017 Red Hat Inc
>> + *
>> + * Authors:
>> + * David Hildenbrand <david@redhat.com>
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU Library General Public License version 2.
>> + */
>> +#include <libcflat.h>
>> +#include <asm/interrupt.h>
>> +#include <asm/barrier.h>
>> +
>> +static bool pgm_int_expected;
>> +static struct lowcore *lc;
>
> Cosmetic suggestion:
> Maybe make it "static struct lowcore const *lc = 0" to be more explicit?
You most probably mean
static struct lowcore *const lc = 0;
(otherwise it won't compile)
makes sense. If I have to resend, I'll add it.
>
> Apart from that, patch looks fine to me now, so with or without that change:
>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
>
Thanks!
--
Thanks,
David
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them
2017-05-31 13:25 ` Thomas Huth
@ 2017-05-31 14:23 ` Paolo Bonzini
0 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2017-05-31 14:23 UTC (permalink / raw)
To: Thomas Huth, David Hildenbrand, kvm
Cc: Radim Krčmář, Christian Borntraeger
On 31/05/2017 15:25, Thomas Huth wrote:
> On 31.05.2017 14:51, Paolo Bonzini wrote:
>>
>>
>> On 31/05/2017 14:39, David Hildenbrand wrote:
>>> + expect_pgm_int();
>>> + *((unsigned int*)-1) = 1;
>>> + check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
>>
>> QEMU gets
>>
>> ABORT: selftest: Unexpected program interrupt: 5 at 0x12b4c, ilen 4
>>
>> It seems that QEMU doesn't point the PSW at the next instruction
>
> David mentioned it in the cover letter ... you likely need this patch
> here first:
>
> http://patchwork.ozlabs.org/patch/768173/
>
> Thomas
>
That helps indeed. :)
Paolo
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-05-31 14:23 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-31 12:39 [kvm-unit-tests PATCH v2 0/2] s390x: program interrupt handler David Hildenbrand
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 1/2] s390x: generate asm offsets for the lowcore David Hildenbrand
2017-05-31 12:39 ` [kvm-unit-tests PATCH v2 2/2] s390x: pgm interrupt handler and a way to test them David Hildenbrand
2017-05-31 12:51 ` Paolo Bonzini
2017-05-31 13:25 ` Thomas Huth
2017-05-31 14:23 ` Paolo Bonzini
2017-05-31 13:26 ` David Hildenbrand
2017-05-31 13:22 ` Thomas Huth
2017-05-31 13:30 ` David Hildenbrand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).