提交 83abeffb 编写于 作者: H Hendrik Brueckner 提交者: Martin Schwidefsky

s390/entry: add assembler macro to conveniently tests under mask

Various functions in entry.S perform test-under-mask instructions
to test for particular bits in memory.  Because test-under-mask uses
a mask value of one byte, the mask value and the offset into the
memory must be calculated manually.  This easily introduces errors
and is hard to review and read.

Introduce the TSTMSK assembler macro to specify a mask constant and
let the macro calculate the offset and the byte mask to generate a
test-under-mask instruction.  The benefit is that existing symbolic
constants can now be used for tests.  Also the macro checks for
zero mask values and mask values that consist of multiple bytes.
Signed-off-by: NHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 0ac27779
...@@ -11,8 +11,16 @@ ...@@ -11,8 +11,16 @@
#ifndef _ASM_S390_NMI_H #ifndef _ASM_S390_NMI_H
#define _ASM_S390_NMI_H #define _ASM_S390_NMI_H
#include <linux/const.h>
#include <linux/types.h> #include <linux/types.h>
#define MCCK_CODE_SYSTEM_DAMAGE _BITUL(63)
#define MCCK_CODE_CPU_TIMER_VALID _BITUL(63 - 46)
#define MCCK_CODE_PSW_MWP_VALID _BITUL(63 - 20)
#define MCCK_CODE_PSW_IA_VALID _BITUL(63 - 23)
#ifndef __ASSEMBLY__
struct mci { struct mci {
__u32 sd : 1; /* 00 system damage */ __u32 sd : 1; /* 00 system damage */
__u32 pd : 1; /* 01 instruction-processing damage */ __u32 pd : 1; /* 01 instruction-processing damage */
...@@ -63,4 +71,5 @@ struct pt_regs; ...@@ -63,4 +71,5 @@ struct pt_regs;
extern void s390_handle_mcck(void); extern void s390_handle_mcck(void);
extern void s390_do_machine_check(struct pt_regs *regs); extern void s390_do_machine_check(struct pt_regs *regs);
#endif /* __ASSEMBLY__ */
#endif /* _ASM_S390_NMI_H */ #endif /* _ASM_S390_NMI_H */
...@@ -5,11 +5,35 @@ ...@@ -5,11 +5,35 @@
#ifndef _ASM_S390_SETUP_H #ifndef _ASM_S390_SETUP_H
#define _ASM_S390_SETUP_H #define _ASM_S390_SETUP_H
#include <linux/const.h>
#include <uapi/asm/setup.h> #include <uapi/asm/setup.h>
#define PARMAREA 0x10400 #define PARMAREA 0x10400
/*
* Machine features detected in head.S
*/
#define MACHINE_FLAG_VM _BITUL(0)
#define MACHINE_FLAG_IEEE _BITUL(1)
#define MACHINE_FLAG_CSP _BITUL(2)
#define MACHINE_FLAG_MVPG _BITUL(3)
#define MACHINE_FLAG_DIAG44 _BITUL(4)
#define MACHINE_FLAG_IDTE _BITUL(5)
#define MACHINE_FLAG_DIAG9C _BITUL(6)
#define MACHINE_FLAG_KVM _BITUL(8)
#define MACHINE_FLAG_ESOP _BITUL(9)
#define MACHINE_FLAG_EDAT1 _BITUL(10)
#define MACHINE_FLAG_EDAT2 _BITUL(11)
#define MACHINE_FLAG_LPAR _BITUL(12)
#define MACHINE_FLAG_LPP _BITUL(13)
#define MACHINE_FLAG_TOPOLOGY _BITUL(14)
#define MACHINE_FLAG_TE _BITUL(15)
#define MACHINE_FLAG_TLB_LC _BITUL(17)
#define MACHINE_FLAG_VX _BITUL(18)
#define MACHINE_FLAG_CAD _BITUL(19)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/lowcore.h> #include <asm/lowcore.h>
...@@ -28,29 +52,6 @@ extern unsigned long max_physmem_end; ...@@ -28,29 +52,6 @@ extern unsigned long max_physmem_end;
extern void detect_memory_memblock(void); extern void detect_memory_memblock(void);
/*
* Machine features detected in head.S
*/
#define MACHINE_FLAG_VM (1UL << 0)
#define MACHINE_FLAG_IEEE (1UL << 1)
#define MACHINE_FLAG_CSP (1UL << 2)
#define MACHINE_FLAG_MVPG (1UL << 3)
#define MACHINE_FLAG_DIAG44 (1UL << 4)
#define MACHINE_FLAG_IDTE (1UL << 5)
#define MACHINE_FLAG_DIAG9C (1UL << 6)
#define MACHINE_FLAG_KVM (1UL << 8)
#define MACHINE_FLAG_ESOP (1UL << 9)
#define MACHINE_FLAG_EDAT1 (1UL << 10)
#define MACHINE_FLAG_EDAT2 (1UL << 11)
#define MACHINE_FLAG_LPAR (1UL << 12)
#define MACHINE_FLAG_LPP (1UL << 13)
#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
#define MACHINE_FLAG_TE (1UL << 15)
#define MACHINE_FLAG_TLB_LC (1UL << 17)
#define MACHINE_FLAG_VX (1UL << 18)
#define MACHINE_FLAG_CAD (1UL << 19)
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
#define MACHINE_IS_LPAR (S390_lowcore.machine_flags & MACHINE_FLAG_LPAR) #define MACHINE_IS_LPAR (S390_lowcore.machine_flags & MACHINE_FLAG_LPAR)
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <asm/sigp.h> #include <asm/sigp.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/vx-insn.h> #include <asm/vx-insn.h>
#include <asm/setup.h>
#include <asm/nmi.h>
__PT_R0 = __PT_GPRS __PT_R0 = __PT_GPRS
__PT_R1 = __PT_GPRS + 8 __PT_R1 = __PT_GPRS + 8
...@@ -138,6 +140,28 @@ _PIF_WORK = (_PIF_PER_TRAP) ...@@ -138,6 +140,28 @@ _PIF_WORK = (_PIF_PER_TRAP)
#endif #endif
.endm .endm
/*
* The TSTMSK macro generates a test-under-mask instruction by
* calculating the memory offset for the specified mask value.
* Mask value can be any constant. The macro shifts the mask
* value to calculate the memory offset for the test-under-mask
* instruction.
*/
.macro TSTMSK addr, mask, size=8, bytepos=0
.if (\bytepos < \size) && (\mask >> 8)
.if (\mask & 0xff)
.error "Mask exceeds byte boundary"
.endif
TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
.exitm
.endif
.ifeq \mask
.error "Mask must not be zero"
.endif
off = \size - \bytepos - 1
tm off+\addr, \mask
.endm
.section .kprobes.text, "ax" .section .kprobes.text, "ax"
/* /*
...@@ -180,7 +204,7 @@ ENTRY(sie64a) ...@@ -180,7 +204,7 @@ ENTRY(sie64a)
stg %r2,__SF_EMPTY(%r15) # save control block pointer stg %r2,__SF_EMPTY(%r15) # save control block pointer
stg %r3,__SF_EMPTY+8(%r15) # save guest register save area stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
xc __SF_EMPTY+16(16,%r15),__SF_EMPTY+16(%r15) # host id & reason xc __SF_EMPTY+16(16,%r15),__SF_EMPTY+16(%r15) # host id & reason
tm __LC_CPU_FLAGS+7,_CIF_FPU # load guest fp/vx registers ? TSTMSK __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ?
jno .Lsie_load_guest_gprs jno .Lsie_load_guest_gprs
brasl %r14,load_fpu_regs # load guest fp/vx regs brasl %r14,load_fpu_regs # load guest fp/vx regs
.Lsie_load_guest_gprs: .Lsie_load_guest_gprs:
...@@ -194,14 +218,14 @@ ENTRY(sie64a) ...@@ -194,14 +218,14 @@ ENTRY(sie64a)
oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now
tm __SIE_PROG20+3(%r14),3 # last exit... tm __SIE_PROG20+3(%r14),3 # last exit...
jnz .Lsie_skip jnz .Lsie_skip
tm __LC_CPU_FLAGS+7,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lsie_skip # exit if fp/vx regs changed jo .Lsie_skip # exit if fp/vx regs changed
tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
jz .Lsie_enter jz .Lsie_enter
.insn s,0xb2800000,__LC_CURRENT_PID # set guest id to pid .insn s,0xb2800000,__LC_CURRENT_PID # set guest id to pid
.Lsie_enter: .Lsie_enter:
sie 0(%r14) sie 0(%r14)
tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
jz .Lsie_skip jz .Lsie_skip
.insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id .insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
.Lsie_skip: .Lsie_skip:
...@@ -270,7 +294,7 @@ ENTRY(system_call) ...@@ -270,7 +294,7 @@ ENTRY(system_call)
stg %r2,__PT_ORIG_GPR2(%r11) stg %r2,__PT_ORIG_GPR2(%r11)
stg %r7,STACK_FRAME_OVERHEAD(%r15) stg %r7,STACK_FRAME_OVERHEAD(%r15)
lgf %r9,0(%r8,%r10) # get system call add. lgf %r9,0(%r8,%r10) # get system call add.
tm __TI_flags+7(%r12),_TIF_TRACE TSTMSK __TI_flags(%r12),_TIF_TRACE
jnz .Lsysc_tracesys jnz .Lsysc_tracesys
basr %r14,%r9 # call sys_xxxx basr %r14,%r9 # call sys_xxxx
stg %r2,__PT_R2(%r11) # store return value stg %r2,__PT_R2(%r11) # store return value
...@@ -278,11 +302,11 @@ ENTRY(system_call) ...@@ -278,11 +302,11 @@ ENTRY(system_call)
.Lsysc_return: .Lsysc_return:
LOCKDEP_SYS_EXIT LOCKDEP_SYS_EXIT
.Lsysc_tif: .Lsysc_tif:
tm __PT_FLAGS+7(%r11),_PIF_WORK TSTMSK __PT_FLAGS(%r11),_PIF_WORK
jnz .Lsysc_work jnz .Lsysc_work
tm __TI_flags+7(%r12),_TIF_WORK TSTMSK __TI_flags(%r12),_TIF_WORK
jnz .Lsysc_work # check for work jnz .Lsysc_work # check for work
tm __LC_CPU_FLAGS+7,_CIF_WORK TSTMSK __LC_CPU_FLAGS,_CIF_WORK
jnz .Lsysc_work jnz .Lsysc_work
.Lsysc_restore: .Lsysc_restore:
lg %r14,__LC_VDSO_PER_CPU lg %r14,__LC_VDSO_PER_CPU
...@@ -298,23 +322,23 @@ ENTRY(system_call) ...@@ -298,23 +322,23 @@ ENTRY(system_call)
# One of the work bits is on. Find out which one. # One of the work bits is on. Find out which one.
# #
.Lsysc_work: .Lsysc_work:
tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING TSTMSK __LC_CPU_FLAGS,_CIF_MCCK_PENDING
jo .Lsysc_mcck_pending jo .Lsysc_mcck_pending
tm __TI_flags+7(%r12),_TIF_NEED_RESCHED TSTMSK __TI_flags(%r12),_TIF_NEED_RESCHED
jo .Lsysc_reschedule jo .Lsysc_reschedule
#ifdef CONFIG_UPROBES #ifdef CONFIG_UPROBES
tm __TI_flags+7(%r12),_TIF_UPROBE TSTMSK __TI_flags(%r12),_TIF_UPROBE
jo .Lsysc_uprobe_notify jo .Lsysc_uprobe_notify
#endif #endif
tm __PT_FLAGS+7(%r11),_PIF_PER_TRAP TSTMSK __PT_FLAGS(%r11),_PIF_PER_TRAP
jo .Lsysc_singlestep jo .Lsysc_singlestep
tm __TI_flags+7(%r12),_TIF_SIGPENDING TSTMSK __TI_flags(%r12),_TIF_SIGPENDING
jo .Lsysc_sigpending jo .Lsysc_sigpending
tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME
jo .Lsysc_notify_resume jo .Lsysc_notify_resume
tm __LC_CPU_FLAGS+7,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lsysc_vxrs jo .Lsysc_vxrs
tm __LC_CPU_FLAGS+7,_CIF_ASCE TSTMSK __LC_CPU_FLAGS,_CIF_ASCE
jo .Lsysc_uaccess jo .Lsysc_uaccess
j .Lsysc_return # beware of critical section cleanup j .Lsysc_return # beware of critical section cleanup
...@@ -353,7 +377,7 @@ ENTRY(system_call) ...@@ -353,7 +377,7 @@ ENTRY(system_call)
.Lsysc_sigpending: .Lsysc_sigpending:
lgr %r2,%r11 # pass pointer to pt_regs lgr %r2,%r11 # pass pointer to pt_regs
brasl %r14,do_signal brasl %r14,do_signal
tm __PT_FLAGS+7(%r11),_PIF_SYSCALL TSTMSK __PT_FLAGS(%r11),_PIF_SYSCALL
jno .Lsysc_return jno .Lsysc_return
lmg %r2,%r7,__PT_R2(%r11) # load svc arguments lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
lg %r10,__TI_sysc_table(%r12) # address of system call table lg %r10,__TI_sysc_table(%r12) # address of system call table
...@@ -413,7 +437,7 @@ ENTRY(system_call) ...@@ -413,7 +437,7 @@ ENTRY(system_call)
basr %r14,%r9 # call sys_xxx basr %r14,%r9 # call sys_xxx
stg %r2,__PT_R2(%r11) # store return value stg %r2,__PT_R2(%r11) # store return value
.Lsysc_tracenogo: .Lsysc_tracenogo:
tm __TI_flags+7(%r12),_TIF_TRACE TSTMSK __TI_flags(%r12),_TIF_TRACE
jz .Lsysc_return jz .Lsysc_return
lgr %r2,%r11 # pass pointer to pt_regs lgr %r2,%r11 # pass pointer to pt_regs
larl %r14,.Lsysc_return larl %r14,.Lsysc_return
...@@ -553,7 +577,7 @@ ENTRY(io_int_handler) ...@@ -553,7 +577,7 @@ ENTRY(io_int_handler)
lghi %r3,THIN_INTERRUPT lghi %r3,THIN_INTERRUPT
.Lio_call: .Lio_call:
brasl %r14,do_IRQ brasl %r14,do_IRQ
tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPAR
jz .Lio_return jz .Lio_return
tpi 0 tpi 0
jz .Lio_return jz .Lio_return
...@@ -563,9 +587,9 @@ ENTRY(io_int_handler) ...@@ -563,9 +587,9 @@ ENTRY(io_int_handler)
LOCKDEP_SYS_EXIT LOCKDEP_SYS_EXIT
TRACE_IRQS_ON TRACE_IRQS_ON
.Lio_tif: .Lio_tif:
tm __TI_flags+7(%r12),_TIF_WORK TSTMSK __TI_flags(%r12),_TIF_WORK
jnz .Lio_work # there is work to do (signals etc.) jnz .Lio_work # there is work to do (signals etc.)
tm __LC_CPU_FLAGS+7,_CIF_WORK TSTMSK __LC_CPU_FLAGS,_CIF_WORK
jnz .Lio_work jnz .Lio_work
.Lio_restore: .Lio_restore:
lg %r14,__LC_VDSO_PER_CPU lg %r14,__LC_VDSO_PER_CPU
...@@ -593,7 +617,7 @@ ENTRY(io_int_handler) ...@@ -593,7 +617,7 @@ ENTRY(io_int_handler)
# check for preemptive scheduling # check for preemptive scheduling
icm %r0,15,__TI_precount(%r12) icm %r0,15,__TI_precount(%r12)
jnz .Lio_restore # preemption is disabled jnz .Lio_restore # preemption is disabled
tm __TI_flags+7(%r12),_TIF_NEED_RESCHED TSTMSK __TI_flags(%r12),_TIF_NEED_RESCHED
jno .Lio_restore jno .Lio_restore
# switch to kernel stack # switch to kernel stack
lg %r1,__PT_R15(%r11) lg %r1,__PT_R15(%r11)
...@@ -625,17 +649,17 @@ ENTRY(io_int_handler) ...@@ -625,17 +649,17 @@ ENTRY(io_int_handler)
# One of the work bits is on. Find out which one. # One of the work bits is on. Find out which one.
# #
.Lio_work_tif: .Lio_work_tif:
tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING TSTMSK __LC_CPU_FLAGS,_CIF_MCCK_PENDING
jo .Lio_mcck_pending jo .Lio_mcck_pending
tm __TI_flags+7(%r12),_TIF_NEED_RESCHED TSTMSK __TI_flags(%r12),_TIF_NEED_RESCHED
jo .Lio_reschedule jo .Lio_reschedule
tm __TI_flags+7(%r12),_TIF_SIGPENDING TSTMSK __TI_flags(%r12),_TIF_SIGPENDING
jo .Lio_sigpending jo .Lio_sigpending
tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME
jo .Lio_notify_resume jo .Lio_notify_resume
tm __LC_CPU_FLAGS+7,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lio_vxrs jo .Lio_vxrs
tm __LC_CPU_FLAGS+7,_CIF_ASCE TSTMSK __LC_CPU_FLAGS,_CIF_ASCE
jo .Lio_uaccess jo .Lio_uaccess
j .Lio_return # beware of critical section cleanup j .Lio_return # beware of critical section cleanup
...@@ -757,12 +781,12 @@ ENTRY(psw_idle) ...@@ -757,12 +781,12 @@ ENTRY(psw_idle)
ENTRY(save_fpu_regs) ENTRY(save_fpu_regs)
lg %r2,__LC_CURRENT lg %r2,__LC_CURRENT
aghi %r2,__TASK_thread aghi %r2,__TASK_thread
tm __LC_CPU_FLAGS+7,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
bor %r14 bor %r14
stfpc __THREAD_FPU_fpc(%r2) stfpc __THREAD_FPU_fpc(%r2)
.Lsave_fpu_regs_fpc_end: .Lsave_fpu_regs_fpc_end:
lg %r3,__THREAD_FPU_regs(%r2) lg %r3,__THREAD_FPU_regs(%r2)
tm __LC_MACHINE_FLAGS+5,4 # MACHINE_HAS_VX TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
jz .Lsave_fpu_regs_fp # no -> store FP regs jz .Lsave_fpu_regs_fp # no -> store FP regs
.Lsave_fpu_regs_vx_low: .Lsave_fpu_regs_vx_low:
VSTM %v0,%v15,0,%r3 # vstm 0,15,0(3) VSTM %v0,%v15,0,%r3 # vstm 0,15,0(3)
...@@ -804,10 +828,10 @@ ENTRY(save_fpu_regs) ...@@ -804,10 +828,10 @@ ENTRY(save_fpu_regs)
load_fpu_regs: load_fpu_regs:
lg %r4,__LC_CURRENT lg %r4,__LC_CURRENT
aghi %r4,__TASK_thread aghi %r4,__TASK_thread
tm __LC_CPU_FLAGS+7,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
bnor %r14 bnor %r14
lfpc __THREAD_FPU_fpc(%r4) lfpc __THREAD_FPU_fpc(%r4)
tm __LC_MACHINE_FLAGS+5,4 # MACHINE_HAS_VX TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
lg %r4,__THREAD_FPU_regs(%r4) # %r4 <- reg save area lg %r4,__THREAD_FPU_regs(%r4) # %r4 <- reg save area
jz .Lload_fpu_regs_fp # -> no VX, load FP regs jz .Lload_fpu_regs_fp # -> no VX, load FP regs
.Lload_fpu_regs_vx: .Lload_fpu_regs_vx:
...@@ -851,11 +875,11 @@ ENTRY(mcck_int_handler) ...@@ -851,11 +875,11 @@ ENTRY(mcck_int_handler)
lg %r12,__LC_THREAD_INFO lg %r12,__LC_THREAD_INFO
larl %r13,cleanup_critical larl %r13,cleanup_critical
lmg %r8,%r9,__LC_MCK_OLD_PSW lmg %r8,%r9,__LC_MCK_OLD_PSW
tm __LC_MCCK_CODE,0x80 # system damage? TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
jo .Lmcck_panic # yes -> rest of mcck code invalid jo .Lmcck_panic # yes -> rest of mcck code invalid
lghi %r14,__LC_CPU_TIMER_SAVE_AREA lghi %r14,__LC_CPU_TIMER_SAVE_AREA
mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
jo 3f jo 3f
la %r14,__LC_SYNC_ENTER_TIMER la %r14,__LC_SYNC_ENTER_TIMER
clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
...@@ -869,7 +893,7 @@ ENTRY(mcck_int_handler) ...@@ -869,7 +893,7 @@ ENTRY(mcck_int_handler)
la %r14,__LC_LAST_UPDATE_TIMER la %r14,__LC_LAST_UPDATE_TIMER
2: spt 0(%r14) 2: spt 0(%r14)
mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
3: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 3: TSTMSK __LC_MCCK_CODE,(MCCK_CODE_PSW_MWP_VALID|MCCK_CODE_PSW_IA_VALID)
jno .Lmcck_panic # no -> skip cleanup critical jno .Lmcck_panic # no -> skip cleanup critical
SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER
.Lmcck_skip: .Lmcck_skip:
...@@ -889,7 +913,7 @@ ENTRY(mcck_int_handler) ...@@ -889,7 +913,7 @@ ENTRY(mcck_int_handler)
la %r11,STACK_FRAME_OVERHEAD(%r1) la %r11,STACK_FRAME_OVERHEAD(%r1)
lgr %r15,%r1 lgr %r15,%r1
ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING TSTMSK __LC_CPU_FLAGS,_CIF_MCCK_PENDING
jno .Lmcck_return jno .Lmcck_return
TRACE_IRQS_OFF TRACE_IRQS_OFF
brasl %r14,s390_handle_mcck brasl %r14,s390_handle_mcck
...@@ -1018,7 +1042,7 @@ cleanup_critical: ...@@ -1018,7 +1042,7 @@ cleanup_critical:
.Lcleanup_sie: .Lcleanup_sie:
lg %r9,__SF_EMPTY(%r15) # get control block pointer lg %r9,__SF_EMPTY(%r15) # get control block pointer
tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
jz 0f jz 0f
.insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id .insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
0: ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 0: ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
...@@ -1173,7 +1197,7 @@ cleanup_critical: ...@@ -1173,7 +1197,7 @@ cleanup_critical:
.quad .Lpsw_idle_lpsw .quad .Lpsw_idle_lpsw
.Lcleanup_save_fpu_regs: .Lcleanup_save_fpu_regs:
tm __LC_CPU_FLAGS+7,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
bor %r14 bor %r14
clg %r9,BASED(.Lcleanup_save_fpu_regs_done) clg %r9,BASED(.Lcleanup_save_fpu_regs_done)
jhe 5f jhe 5f
...@@ -1191,7 +1215,7 @@ cleanup_critical: ...@@ -1191,7 +1215,7 @@ cleanup_critical:
stfpc __THREAD_FPU_fpc(%r2) stfpc __THREAD_FPU_fpc(%r2)
1: # Load register save area and check if VX is active 1: # Load register save area and check if VX is active
lg %r3,__THREAD_FPU_regs(%r2) lg %r3,__THREAD_FPU_regs(%r2)
tm __LC_MACHINE_FLAGS+5,4 # MACHINE_HAS_VX TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
jz 4f # no VX -> store FP regs jz 4f # no VX -> store FP regs
2: # Store vector registers (V0-V15) 2: # Store vector registers (V0-V15)
VSTM %v0,%v15,0,%r3 # vstm 0,15,0(3) VSTM %v0,%v15,0,%r3 # vstm 0,15,0(3)
...@@ -1231,7 +1255,7 @@ cleanup_critical: ...@@ -1231,7 +1255,7 @@ cleanup_critical:
.quad .Lsave_fpu_regs_done .quad .Lsave_fpu_regs_done
.Lcleanup_load_fpu_regs: .Lcleanup_load_fpu_regs:
tm __LC_CPU_FLAGS+7,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
bnor %r14 bnor %r14
clg %r9,BASED(.Lcleanup_load_fpu_regs_done) clg %r9,BASED(.Lcleanup_load_fpu_regs_done)
jhe 1f jhe 1f
...@@ -1244,7 +1268,7 @@ cleanup_critical: ...@@ -1244,7 +1268,7 @@ cleanup_critical:
lg %r4,__LC_CURRENT lg %r4,__LC_CURRENT
aghi %r4,__TASK_thread aghi %r4,__TASK_thread
lfpc __THREAD_FPU_fpc(%r4) lfpc __THREAD_FPU_fpc(%r4)
tm __LC_MACHINE_FLAGS+5,4 # MACHINE_HAS_VX TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
lg %r4,__THREAD_FPU_regs(%r4) # %r4 <- reg save area lg %r4,__THREAD_FPU_regs(%r4) # %r4 <- reg save area
jz 2f # -> no VX, load FP regs jz 2f # -> no VX, load FP regs
4: # Load V0 ..V15 registers 4: # Load V0 ..V15 registers
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册