aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kernel/entry64.S25
1 files changed, 20 insertions, 5 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7a2d22dda9ef..14eec6a9577e 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -80,14 +80,21 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
80#endif 80#endif
81 .endm 81 .endm
82 82
83 .macro HANDLE_SIE_INTERCEPT scratch 83 .macro HANDLE_SIE_INTERCEPT scratch,pgmcheck
84#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 84#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
85 tmhh %r8,0x0001 # interrupting from user ? 85 tmhh %r8,0x0001 # interrupting from user ?
86 jnz .+42 86 jnz .+42
87 lgr \scratch,%r9 87 lgr \scratch,%r9
88 slg \scratch,BASED(.Lsie_loop) 88 slg \scratch,BASED(.Lsie_loop)
89 clg \scratch,BASED(.Lsie_length) 89 clg \scratch,BASED(.Lsie_length)
90 .if \pgmcheck
91 # Some program interrupts are suppressing (e.g. protection).
92 # We must also check the instruction after SIE in that case.
93 # do_protection_exception will rewind to rewind_pad
94 jh .+22
95 .else
90 jhe .+22 96 jhe .+22
97 .endif
91 lg %r9,BASED(.Lsie_loop) 98 lg %r9,BASED(.Lsie_loop)
92 SPP BASED(.Lhost_id) # set host id 99 SPP BASED(.Lhost_id) # set host id
93#endif 100#endif
@@ -390,7 +397,7 @@ ENTRY(pgm_check_handler)
390 lg %r12,__LC_THREAD_INFO 397 lg %r12,__LC_THREAD_INFO
391 larl %r13,system_call 398 larl %r13,system_call
392 lmg %r8,%r9,__LC_PGM_OLD_PSW 399 lmg %r8,%r9,__LC_PGM_OLD_PSW
393 HANDLE_SIE_INTERCEPT %r14 400 HANDLE_SIE_INTERCEPT %r14,1
394 tmhh %r8,0x0001 # test problem state bit 401 tmhh %r8,0x0001 # test problem state bit
395 jnz 1f # -> fault in user space 402 jnz 1f # -> fault in user space
396 tmhh %r8,0x4000 # PER bit set in old PSW ? 403 tmhh %r8,0x4000 # PER bit set in old PSW ?
@@ -466,7 +473,7 @@ ENTRY(io_int_handler)
466 lg %r12,__LC_THREAD_INFO 473 lg %r12,__LC_THREAD_INFO
467 larl %r13,system_call 474 larl %r13,system_call
468 lmg %r8,%r9,__LC_IO_OLD_PSW 475 lmg %r8,%r9,__LC_IO_OLD_PSW
469 HANDLE_SIE_INTERCEPT %r14 476 HANDLE_SIE_INTERCEPT %r14,0
470 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 477 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
471 tmhh %r8,0x0001 # interrupting from user? 478 tmhh %r8,0x0001 # interrupting from user?
472 jz io_skip 479 jz io_skip
@@ -612,7 +619,7 @@ ENTRY(ext_int_handler)
612 lg %r12,__LC_THREAD_INFO 619 lg %r12,__LC_THREAD_INFO
613 larl %r13,system_call 620 larl %r13,system_call
614 lmg %r8,%r9,__LC_EXT_OLD_PSW 621 lmg %r8,%r9,__LC_EXT_OLD_PSW
615 HANDLE_SIE_INTERCEPT %r14 622 HANDLE_SIE_INTERCEPT %r14,0
616 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 623 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
617 tmhh %r8,0x0001 # interrupting from user ? 624 tmhh %r8,0x0001 # interrupting from user ?
618 jz ext_skip 625 jz ext_skip
@@ -660,7 +667,7 @@ ENTRY(mcck_int_handler)
660 lg %r12,__LC_THREAD_INFO 667 lg %r12,__LC_THREAD_INFO
661 larl %r13,system_call 668 larl %r13,system_call
662 lmg %r8,%r9,__LC_MCK_OLD_PSW 669 lmg %r8,%r9,__LC_MCK_OLD_PSW
663 HANDLE_SIE_INTERCEPT %r14 670 HANDLE_SIE_INTERCEPT %r14,0
664 tm __LC_MCCK_CODE,0x80 # system damage? 671 tm __LC_MCCK_CODE,0x80 # system damage?
665 jo mcck_panic # yes -> rest of mcck code invalid 672 jo mcck_panic # yes -> rest of mcck code invalid
666 lghi %r14,__LC_CPU_TIMER_SAVE_AREA 673 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
@@ -959,6 +966,13 @@ ENTRY(sie64a)
959 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area 966 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
960 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0 967 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
961 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 968 lmg %r0,%r13,0(%r3) # load guest gprs 0-13
969# some program checks are suppressing. C code (e.g. do_protection_exception)
970# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
971# instructions in the sie_loop should not cause program interrupts. So
972# lets use a nop (47 00 00 00) as a landing pad.
973# See also HANDLE_SIE_INTERCEPT
974rewind_pad:
975 nop 0
962sie_loop: 976sie_loop:
963 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 977 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
964 tm __TI_flags+7(%r14),_TIF_EXIT_SIE 978 tm __TI_flags+7(%r14),_TIF_EXIT_SIE
@@ -998,6 +1012,7 @@ sie_fault:
998.Lhost_id: 1012.Lhost_id:
999 .quad 0 1013 .quad 0
1000 1014
1015 EX_TABLE(rewind_pad,sie_fault)
1001 EX_TABLE(sie_loop,sie_fault) 1016 EX_TABLE(sie_loop,sie_fault)
1002#endif 1017#endif
1003 1018