diff options
Diffstat (limited to 'arch/s390/kernel/entry64.S')
| -rw-r--r-- | arch/s390/kernel/entry64.S | 139 | 
1 files changed, 80 insertions, 59 deletions
| diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 412a7b8783d7..4e1c292fa7e3 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -2,7 +2,7 @@   *  arch/s390/kernel/entry64.S   *    S390 low-level entry points.   * - *    Copyright (C) IBM Corp. 1999,2010 + *    Copyright (C) IBM Corp. 1999,2012   *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),   *		 Hartmut Penner (hp@de.ibm.com),   *		 Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), @@ -489,7 +489,6 @@ io_restore:  	lg	%r14,__LC_VDSO_PER_CPU  	lmg	%r0,%r10,__PT_R0(%r11)  	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11) -	ni	__LC_RETURN_PSW+1,0xfd	# clear wait state bit  	stpt	__LC_EXIT_TIMER  	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER  	lmg	%r11,%r15,__PT_R11(%r11) @@ -625,12 +624,30 @@ ext_skip:  	TRACE_IRQS_OFF  	lghi	%r1,4096  	lgr	%r2,%r11		# pass pointer to pt_regs -	llgf	%r3,__LC_CPU_ADDRESS	# get cpu address + interruption code +	llgf	%r3,__LC_EXT_CPU_ADDR	# get cpu address + interruption code  	llgf	%r4,__LC_EXT_PARAMS	# get external parameter  	lg	%r5,__LC_EXT_PARAMS2-4096(%r1)	# get 64 bit external parameter  	brasl	%r14,do_extint  	j	io_return +/* + * Load idle PSW. The second "half" of this function is in cleanup_idle. + */ +ENTRY(psw_idle) +	stg	%r4,__SF_EMPTY(%r15) +	larl	%r1,psw_idle_lpsw+4 +	stg	%r1,__SF_EMPTY+8(%r15) +	larl	%r1,.Lvtimer_max +	stck	__IDLE_ENTER(%r2) +	ltr	%r5,%r5 +	stpt	__VQ_IDLE_ENTER(%r3) +	jz	psw_idle_lpsw +	spt	0(%r1) +psw_idle_lpsw: +	lpswe	__SF_EMPTY(%r15) +	br	%r14 +psw_idle_end: +  __critical_end:  /* @@ -696,7 +713,6 @@ mcck_return:  	lg	%r14,__LC_VDSO_PER_CPU  	lmg	%r0,%r10,__PT_R0(%r11)  	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW -	ni	__LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit  	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?  	jno	0f  	stpt	__LC_EXIT_TIMER @@ -713,68 +729,30 @@ mcck_panic:  0:	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)  	j	mcck_skip -/* - * Restart interruption handler, kick starter for additional CPUs - */ -#ifdef CONFIG_SMP -	__CPUINIT -ENTRY(restart_int_handler) -	basr	%r1,0 -restart_base: -	spt	restart_vtime-restart_base(%r1) -	stck	__LC_LAST_UPDATE_CLOCK -	mvc	__LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) -	mvc	__LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) -	lghi	%r10,__LC_GPREGS_SAVE_AREA -	lg	%r15,120(%r10)		# load ksp -	lghi	%r10,__LC_CREGS_SAVE_AREA -	lctlg	%c0,%c15,0(%r10)	# get new ctl regs -	lghi	%r10,__LC_AREGS_SAVE_AREA -	lam	%a0,%a15,0(%r10) -	lmg	%r6,%r15,__SF_GPRS(%r15)# load registers from clone -	lg	%r1,__LC_THREAD_INFO -	mvc	__LC_USER_TIMER(8),__TI_user_timer(%r1) -	mvc	__LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) -	xc	__LC_STEAL_TIMER(8),__LC_STEAL_TIMER -	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off -	brasl	%r14,start_secondary -	.align	8 -restart_vtime: -	.long	0x7fffffff,0xffffffff -	.previous -#else -/* - * If we do not run with SMP enabled, let the new CPU crash ... - */ -ENTRY(restart_int_handler) -	basr	%r1,0 -restart_base: -	lpswe	restart_crash-restart_base(%r1) -	.align 8 -restart_crash: -	.long  0x000a0000,0x00000000,0x00000000,0x00000000 -restart_go: -#endif -  #  # PSW restart interrupt handler  # -ENTRY(psw_restart_int_handler) +ENTRY(restart_int_handler)  	stg	%r15,__LC_SAVE_AREA_RESTART -	larl	%r15,restart_stack		# load restart stack -	lg	%r15,0(%r15) +	lg	%r15,__LC_RESTART_STACK  	aghi	%r15,-__PT_SIZE			# create pt_regs on stack +	xc	0(__PT_SIZE,%r15),0(%r15)  	stmg	%r0,%r14,__PT_R0(%r15)  	mvc	__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART  	mvc	__PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw -	aghi	%r15,-STACK_FRAME_OVERHEAD -	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) -	brasl	%r14,do_restart -	larl	%r14,restart_psw_crash		# load disabled wait PSW if -	lpswe	0(%r14)				# do_restart returns -	.align 8 -restart_psw_crash: -	.quad	0x0002000080000000,0x0000000000000000 + restart_psw_crash +	aghi	%r15,-STACK_FRAME_OVERHEAD	# create stack frame on stack +	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15) +	lmg	%r1,%r3,__LC_RESTART_FN		# load fn, parm & source cpu +	ltgr	%r3,%r3				# test source cpu address +	jm	1f				# negative -> skip source stop +0:	sigp	%r4,%r3,1			# sigp sense to source cpu +	brc	10,0b				# wait for status stored +1:	basr	%r14,%r1			# call function +	stap	__SF_EMPTY(%r15)		# store cpu address +	llgh	%r3,__SF_EMPTY(%r15) +2:	sigp	%r4,%r3,5			# sigp stop to current cpu +	brc	2,2b +3:	j	3b  	.section .kprobes.text, "ax" @@ -808,6 +786,8 @@ cleanup_table:  	.quad	io_tif  	.quad	io_restore  	.quad	io_done +	.quad	psw_idle +	.quad	psw_idle_end  cleanup_critical:  	clg	%r9,BASED(cleanup_table)	# system_call @@ -826,6 +806,10 @@ cleanup_critical:  	jl	cleanup_io_tif  	clg	%r9,BASED(cleanup_table+56)	# io_done  	jl	cleanup_io_restore +	clg	%r9,BASED(cleanup_table+64)	# psw_idle +	jl	0f +	clg	%r9,BASED(cleanup_table+72)	# psw_idle_end +	jl	cleanup_idle  0:	br	%r14 @@ -915,7 +899,6 @@ cleanup_io_restore:  	je	0f  	lg	%r9,24(%r11)		# get saved r11 pointer to pt_regs  	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9) -	ni	__LC_RETURN_PSW+1,0xfd	# clear wait state bit  	mvc	0(64,%r11),__PT_R8(%r9)  	lmg	%r0,%r7,__PT_R0(%r9)  0:	lmg	%r8,%r9,__LC_RETURN_PSW @@ -923,6 +906,42 @@ cleanup_io_restore:  cleanup_io_restore_insn:  	.quad	io_done - 4 +cleanup_idle: +	# copy interrupt clock & cpu timer +	mvc	__IDLE_EXIT(8,%r2),__LC_INT_CLOCK +	mvc	__VQ_IDLE_EXIT(8,%r3),__LC_ASYNC_ENTER_TIMER +	cghi	%r11,__LC_SAVE_AREA_ASYNC +	je	0f +	mvc	__IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK +	mvc	__VQ_IDLE_EXIT(8,%r3),__LC_MCCK_ENTER_TIMER +0:	# check if stck & stpt have been executed +	clg	%r9,BASED(cleanup_idle_insn) +	jhe	1f +	mvc	__IDLE_ENTER(8,%r2),__IDLE_EXIT(%r2) +	mvc	__VQ_IDLE_ENTER(8,%r3),__VQ_IDLE_EXIT(%r3) +	j	2f +1:	# check if the cpu timer has been reprogrammed +	ltr	%r5,%r5 +	jz	2f +	spt	__VQ_IDLE_ENTER(%r3) +2:	# account system time going idle +	lg	%r9,__LC_STEAL_TIMER +	alg	%r9,__IDLE_ENTER(%r2) +	slg	%r9,__LC_LAST_UPDATE_CLOCK +	stg	%r9,__LC_STEAL_TIMER +	mvc	__LC_LAST_UPDATE_CLOCK(8),__IDLE_EXIT(%r2) +	lg	%r9,__LC_SYSTEM_TIMER +	alg	%r9,__LC_LAST_UPDATE_TIMER +	slg	%r9,__VQ_IDLE_ENTER(%r3) +	stg	%r9,__LC_SYSTEM_TIMER +	mvc	__LC_LAST_UPDATE_TIMER(8),__VQ_IDLE_EXIT(%r3) +	# prepare return psw +	nihh	%r8,0xfffd		# clear wait state bit +	lg	%r9,48(%r11)		# return from psw_idle +	br	%r14 +cleanup_idle_insn: +	.quad	psw_idle_lpsw +  /*   * Integer constants   */ @@ -931,6 +950,8 @@ cleanup_io_restore_insn:  	.quad	__critical_start  .Lcritical_length:  	.quad	__critical_end - __critical_start +.Lvtimer_max: +	.quad	0x7fffffffffffffff  #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 
