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@xxxxxxxxxxxxxxxxxx> Reviewed-by: Thomas Huth <thuth@xxxxxxxxxx> Reviewed-by: David Hildenbrand <david@xxxxxxxxxx> --- lib/s390x/asm/arch_def.h | 10 ++++++++++ lib/s390x/interrupt.c | 7 +++++++ 2 files changed, 17 insertions(+) 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: -- 2.7.4