|
@@ -80,14 +80,21 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
|
|
|
#endif
|
|
|
.endm
|
|
|
|
|
|
- .macro HANDLE_SIE_INTERCEPT scratch
|
|
|
+ .macro HANDLE_SIE_INTERCEPT scratch,pgmcheck
|
|
|
#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
|
|
|
tmhh %r8,0x0001 # interrupting from user ?
|
|
|
jnz .+42
|
|
|
lgr \scratch,%r9
|
|
|
slg \scratch,BASED(.Lsie_loop)
|
|
|
clg \scratch,BASED(.Lsie_length)
|
|
|
+ .if \pgmcheck
|
|
|
+ # Some program interrupts are suppressing (e.g. protection).
|
|
|
+ # We must also check the instruction after SIE in that case.
|
|
|
+ # do_protection_exception will rewind to rewind_pad
|
|
|
+ jh .+22
|
|
|
+ .else
|
|
|
jhe .+22
|
|
|
+ .endif
|
|
|
lg %r9,BASED(.Lsie_loop)
|
|
|
SPP BASED(.Lhost_id) # set host id
|
|
|
#endif
|
|
@@ -390,7 +397,7 @@ ENTRY(pgm_check_handler)
|
|
|
lg %r12,__LC_THREAD_INFO
|
|
|
larl %r13,system_call
|
|
|
lmg %r8,%r9,__LC_PGM_OLD_PSW
|
|
|
- HANDLE_SIE_INTERCEPT %r14
|
|
|
+ HANDLE_SIE_INTERCEPT %r14,1
|
|
|
tmhh %r8,0x0001 # test problem state bit
|
|
|
jnz 1f # -> fault in user space
|
|
|
tmhh %r8,0x4000 # PER bit set in old PSW ?
|
|
@@ -466,7 +473,7 @@ ENTRY(io_int_handler)
|
|
|
lg %r12,__LC_THREAD_INFO
|
|
|
larl %r13,system_call
|
|
|
lmg %r8,%r9,__LC_IO_OLD_PSW
|
|
|
- HANDLE_SIE_INTERCEPT %r14
|
|
|
+ HANDLE_SIE_INTERCEPT %r14,0
|
|
|
SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
|
|
|
tmhh %r8,0x0001 # interrupting from user?
|
|
|
jz io_skip
|
|
@@ -612,7 +619,7 @@ ENTRY(ext_int_handler)
|
|
|
lg %r12,__LC_THREAD_INFO
|
|
|
larl %r13,system_call
|
|
|
lmg %r8,%r9,__LC_EXT_OLD_PSW
|
|
|
- HANDLE_SIE_INTERCEPT %r14
|
|
|
+ HANDLE_SIE_INTERCEPT %r14,0
|
|
|
SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
|
|
|
tmhh %r8,0x0001 # interrupting from user ?
|
|
|
jz ext_skip
|
|
@@ -660,7 +667,7 @@ ENTRY(mcck_int_handler)
|
|
|
lg %r12,__LC_THREAD_INFO
|
|
|
larl %r13,system_call
|
|
|
lmg %r8,%r9,__LC_MCK_OLD_PSW
|
|
|
- HANDLE_SIE_INTERCEPT %r14
|
|
|
+ HANDLE_SIE_INTERCEPT %r14,0
|
|
|
tm __LC_MCCK_CODE,0x80 # system damage?
|
|
|
jo mcck_panic # yes -> rest of mcck code invalid
|
|
|
lghi %r14,__LC_CPU_TIMER_SAVE_AREA
|
|
@@ -959,6 +966,13 @@ ENTRY(sie64a)
|
|
|
stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
|
|
|
xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
|
|
|
lmg %r0,%r13,0(%r3) # load guest gprs 0-13
|
|
|
+# some program checks are suppressing. C code (e.g. do_protection_exception)
|
|
|
+# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
|
|
|
+# instructions in the sie_loop should not cause program interrupts. So
|
|
|
+# lets use a nop (47 00 00 00) as a landing pad.
|
|
|
+# See also HANDLE_SIE_INTERCEPT
|
|
|
+rewind_pad:
|
|
|
+ nop 0
|
|
|
sie_loop:
|
|
|
lg %r14,__LC_THREAD_INFO # pointer thread_info struct
|
|
|
tm __TI_flags+7(%r14),_TIF_EXIT_SIE
|
|
@@ -998,6 +1012,7 @@ sie_fault:
|
|
|
.Lhost_id:
|
|
|
.quad 0
|
|
|
|
|
|
+ EX_TABLE(rewind_pad,sie_fault)
|
|
|
EX_TABLE(sie_loop,sie_fault)
|
|
|
#endif
|
|
|
|