[kvm-unit-tests,PULL,2/8] s390x: Add privileged operation exceptions handling
diff mbox

Message ID 1522222784-7709-3-git-send-email-thuth@redhat.com
State New
Headers show

Commit Message

Thomas Huth March 28, 2018, 7:39 a.m. UTC
From: Janosch Frank <frankja@linux.vnet.ibm.com>

A huge part of the emulated instructions are privileged and result in
an operation exception, when executed in problem state.

To be able to test this, we introduce the enter_pstate function, that
sets the cpu to the problem state. Also we extend the interrupt
handler, so it resets us to supervisor mode again, when we hit the
privileged operation exception.

Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 lib/s390x/asm/arch_def.h | 10 ++++++++++
 lib/s390x/interrupt.c    |  7 +++++++
 2 files changed, 17 insertions(+)

Patch
diff mbox

diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
index 620dca4..b67afac 100644
--- a/lib/s390x/asm/arch_def.h
+++ b/lib/s390x/asm/arch_def.h
@@ -16,6 +16,7 @@  struct psw {
 };
 
 #define PSW_MASK_DAT			0x0400000000000000UL
+#define PSW_MASK_PSTATE			0x0001000000000000UL
 
 struct lowcore {
 	uint8_t		pad_0x0000[0x0080 - 0x0000];	/* 0x0000 */
@@ -209,4 +210,13 @@  static inline void load_psw_mask(uint64_t mask)
 		: "+r" (tmp) :  "a" (&psw) : "memory", "cc" );
 }
 
+static inline void enter_pstate(void)
+{
+	uint64_t mask;
+
+	mask = extract_psw_mask();
+	mask |= PSW_MASK_PSTATE;
+	load_psw_mask(mask);
+}
+
 #endif
diff --git a/lib/s390x/interrupt.c b/lib/s390x/interrupt.c
index 67d581b..56c7603 100644
--- a/lib/s390x/interrupt.c
+++ b/lib/s390x/interrupt.c
@@ -44,6 +44,13 @@  void check_pgm_int_code(uint16_t code)
 static void fixup_pgm_int(void)
 {
 	switch (lc->pgm_int_code) {
+	case PGM_INT_CODE_PRIVILEGED_OPERATION:
+		/* Normal operation is in supervisor state, so this exception
+		 * was produced intentionally and we should return to the
+		 * supervisor state.
+		 */
+		lc->pgm_old_psw.mask &= ~PSW_MASK_PSTATE;
+		break;
 	case PGM_INT_CODE_SEGMENT_TRANSLATION:
 	case PGM_INT_CODE_PAGE_TRANSLATION:
 	case PGM_INT_CODE_TRACE_TABLE: