cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

entry-common.S (8743B)


      1/* SPDX-License-Identifier: GPL-2.0
      2 *
      3 *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
      4 *  Copyright (C) 2003 - 2008  Paul Mundt
      5 */
      6
      7! NOTE:
      8! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
      9! to be jumped is too far, but it causes illegal slot exception.
     10
     11/*	
     12 * entry.S contains the system-call and fault low-level handling routines.
     13 * This also contains the timer-interrupt handler, as well as all interrupts
     14 * and faults that can result in a task-switch.
     15 *
     16 * NOTE: This code handles signal-recognition, which happens every time
     17 * after a timer-interrupt and after each system call.
     18 *
     19 * NOTE: This code uses a convention that instructions in the delay slot
     20 * of a transfer-control instruction are indented by an extra space, thus:
     21 *
     22 *    jmp	@k0	    ! control-transfer instruction
     23 *     ldc	k1, ssr     ! delay slot
     24 *
     25 * Stack layout in 'ret_from_syscall':
     26 * 	ptrace needs to have all regs on the stack.
     27 *	if the order here is changed, it needs to be
     28 *	updated in ptrace.c and ptrace.h
     29 *
     30 *	r0
     31 *      ...
     32 *	r15 = stack pointer
     33 *	spc
     34 *	pr
     35 *	ssr
     36 *	gbr
     37 *	mach
     38 *	macl
     39 *	syscall #
     40 *
     41 */
     42#include <asm/dwarf.h>
     43
     44#if defined(CONFIG_PREEMPTION)
     45#  define preempt_stop()	cli ; TRACE_IRQS_OFF
     46#else
     47#  define preempt_stop()
     48#  define resume_kernel		__restore_all
     49#endif
     50
     51
     52	.align	2
     53ENTRY(exception_error)
     54	!
     55	TRACE_IRQS_ON
     56	sti
     57	mov.l	1f, r0
     58	jmp	@r0
     59	 nop
     60
     61	.align	2
     621:	.long	do_exception_error
     63
     64	.align	2
     65ret_from_exception:
     66	CFI_STARTPROC simple
     67	CFI_DEF_CFA r14, 0
     68	CFI_REL_OFFSET 17, 64
     69	CFI_REL_OFFSET 15, 60
     70	CFI_REL_OFFSET 14, 56
     71	CFI_REL_OFFSET 13, 52
     72	CFI_REL_OFFSET 12, 48
     73	CFI_REL_OFFSET 11, 44
     74	CFI_REL_OFFSET 10, 40
     75	CFI_REL_OFFSET 9, 36
     76	CFI_REL_OFFSET 8, 32
     77	preempt_stop()
     78ENTRY(ret_from_irq)
     79	!
     80	mov	#OFF_SR, r0
     81	mov.l	@(r0,r15), r0	! get status register
     82	shll	r0
     83	shll	r0		! kernel space?
     84	get_current_thread_info r8, r0
     85	bt	resume_kernel	! Yes, it's from kernel, go back soon
     86
     87#ifdef CONFIG_PREEMPTION
     88	bra	resume_userspace
     89	 nop
     90ENTRY(resume_kernel)
     91	cli
     92	TRACE_IRQS_OFF
     93	mov.l	@(TI_PRE_COUNT,r8), r0	! current_thread_info->preempt_count
     94	tst	r0, r0
     95	bf	noresched
     96need_resched:
     97	mov.l	@(TI_FLAGS,r8), r0	! current_thread_info->flags
     98	tst	#_TIF_NEED_RESCHED, r0	! need_resched set?
     99	bt	noresched
    100
    101	mov	#OFF_SR, r0
    102	mov.l	@(r0,r15), r0		! get status register
    103	shlr	r0
    104	and	#(0xf0>>1), r0		! interrupts off (exception path)?
    105	cmp/eq	#(0xf0>>1), r0
    106	bt	noresched
    107	mov.l	1f, r0
    108	jsr	@r0			! call preempt_schedule_irq
    109	 nop
    110	bra	need_resched
    111	 nop
    112
    113noresched:
    114	bra	__restore_all
    115	 nop
    116
    117	.align 2
    1181:	.long	preempt_schedule_irq
    119#endif
    120
    121ENTRY(resume_userspace)
    122	! r8: current_thread_info
    123	cli
    124	TRACE_IRQS_OFF
    125	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
    126	tst	#(_TIF_WORK_MASK & 0xff), r0
    127	bt/s	__restore_all
    128	 tst	#_TIF_NEED_RESCHED, r0
    129
    130	.align	2
    131work_pending:
    132	! r0: current_thread_info->flags
    133	! r8: current_thread_info
    134	! t:  result of "tst	#_TIF_NEED_RESCHED, r0"
    135	bf/s	work_resched
    136	 tst	#(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME), r0
    137work_notifysig:
    138	bt/s	__restore_all
    139	 mov	r15, r4
    140	mov	r12, r5		! set arg1(save_r0)
    141	mov	r0, r6
    142	sti
    143	mov.l	2f, r1
    144	mov.l	3f, r0
    145	jmp	@r1
    146	 lds	r0, pr
    147work_resched:
    148	mov.l	1f, r1
    149	jsr	@r1				! schedule
    150	 nop
    151	cli
    152	TRACE_IRQS_OFF
    153	!
    154	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
    155	tst	#(_TIF_WORK_MASK & 0xff), r0
    156	bt	__restore_all
    157	bra	work_pending
    158	 tst	#_TIF_NEED_RESCHED, r0
    159
    160	.align	2
    1611:	.long	schedule
    1622:	.long	do_notify_resume
    1633:	.long	resume_userspace
    164
    165	.align	2
    166syscall_exit_work:
    167	! r0: current_thread_info->flags
    168	! r8: current_thread_info
    169	tst	#(_TIF_WORK_SYSCALL_MASK & 0xff), r0
    170	bt/s	work_pending
    171	 tst	#_TIF_NEED_RESCHED, r0
    172	TRACE_IRQS_ON
    173	sti
    174	mov	r15, r4
    175	mov.l	8f, r0			! do_syscall_trace_leave
    176	jsr	@r0
    177	 nop
    178	bra	resume_userspace
    179	 nop
    180
    181__restore_all:
    182	mov	#OFF_SR, r0
    183	mov.l	@(r0,r15), r0	! get status register
    184
    185	shlr2	r0
    186	and	#0x3c, r0
    187	cmp/eq	#0x3c, r0
    188	bt	1f
    189	TRACE_IRQS_ON
    190	bra	2f
    191	 nop
    1921:
    193	TRACE_IRQS_OFF
    1942:
    195	mov.l	3f, r0
    196	jmp	@r0
    197	 nop
    198
    199	.align	2
    2003:	.long	restore_all
    201
    202	.align	2
    203syscall_badsys:			! Bad syscall number
    204	get_current_thread_info r8, r0
    205	mov	#-ENOSYS, r0
    206	bra	resume_userspace
    207	 mov.l	r0, @(OFF_R0,r15)	! Return value
    208
    209/*
    210 * The main debug trap handler.
    211 *
    212 * r8=TRA (not the trap number!)
    213 *
    214 * Note: This assumes that the trapa value is left in its original
    215 * form (without the shlr2 shift) so the calculation for the jump
    216 * call table offset remains a simple in place mask.
    217 */
    218debug_trap:
    219	mov	r8, r0
    220	and	#(0xf << 2), r0
    221	mov.l	1f, r8
    222	add	r0, r8
    223	mov.l	@r8, r8
    224	jsr	@r8
    225	 nop
    226	bra	ret_from_exception
    227	 nop
    228	CFI_ENDPROC
    229
    230	.align	2
    2311:	.long	debug_trap_table
    232
    233/*
    234 * Syscall interface:
    235 *
    236 *	Syscall #: R3
    237 *	Arguments #0 to #3: R4--R7
    238 *	Arguments #4 to #6: R0, R1, R2
    239 *	TRA: See following table.
    240 *
    241 * (TRA>>2)	Purpose
    242 * --------	-------
    243 * 0x00-0x0f	original SH-3/4 syscall ABI (not in general use).
    244 * 0x10-0x1f	general SH-3/4 syscall ABI.
    245 *      0x1f	unified SH-2/3/4 syscall ABI (preferred).
    246 * 0x20-0x2f	original SH-2 syscall ABI.
    247 * 0x30-0x3f	debug traps used by the kernel.
    248 * 0x40-0xff	Not supported by all parts, so left unhandled.
    249 *
    250 * For making system calls, any trap number in the range for the
    251 * given cpu model may be used, but the unified trap number 0x1f is
    252 * preferred for compatibility with all models.
    253 *
    254 * The low bits of the trap number were once documented as matching
    255 * the number of arguments, but they were never actually used as such
    256 * by the kernel. SH-2 originally used its own separate trap range
    257 * because several hardware exceptions fell in the range used for the
    258 * SH-3/4 syscall ABI.
    259 *
    260 * This code also handles delegating other traps to the BIOS/gdb stub.
    261 *
    262 * Note: When we're first called, the TRA value must be shifted
    263 * right 2 bits in order to get the value that was used as the "trapa"
    264 * argument.
    265 */
    266
    267	.align	2
    268	.globl	ret_from_fork
    269ret_from_fork:
    270	mov.l	1f, r8
    271	jsr	@r8
    272	 mov	r0, r4
    273	bra	syscall_exit
    274	 nop
    275
    276	.align	2
    277	.globl	ret_from_kernel_thread
    278ret_from_kernel_thread:
    279	mov.l	1f, r8
    280	jsr	@r8
    281	 mov	r0, r4
    282	mov.l	@(OFF_R5,r15), r5   ! fn
    283	jsr	@r5
    284	 mov.l	@(OFF_R4,r15), r4   ! arg
    285	bra	syscall_exit
    286	 nop
    287
    288	.align	2
    2891:	.long	schedule_tail
    290
    291/*
    292 * The poorly named main trapa decode and dispatch routine, for
    293 * system calls and debug traps through their respective jump tables.
    294 */
    295ENTRY(system_call)
    296	setup_frame_reg
    297#if !defined(CONFIG_CPU_SH2)
    298	mov.l	1f, r9
    299	mov.l	@r9, r8		! Read from TRA (Trap Address) Register
    300#endif
    301
    302	mov	#OFF_TRA, r10
    303	add	r15, r10
    304	mov.l	r8, @r10		! set TRA value to tra
    305
    306	/*
    307	 * Check the trap type
    308	 */
    309	mov	#((0x20 << 2) - 1), r9
    310	cmp/hi	r9, r8
    311	bt/s	debug_trap		! it's a debug trap..
    312	 nop
    313
    314	TRACE_IRQS_ON
    315	sti
    316
    317	!
    318	get_current_thread_info r8, r10
    319	mov.l	@(TI_FLAGS,r8), r8
    320	mov	#(_TIF_WORK_SYSCALL_MASK & 0xff), r10
    321	mov	#(_TIF_WORK_SYSCALL_MASK >> 8), r9
    322	tst	r10, r8
    323	shll8	r9
    324	bf	syscall_trace_entry
    325	tst	r9, r8
    326	bf	syscall_trace_entry
    327	!
    328	mov.l	6f, r8			! Number of syscalls
    329	cmp/hs	r8, r3
    330	bt	syscall_badsys
    331	!
    332syscall_call:
    333	shll2	r3		! x4
    334	mov.l	3f, r8		! Load the address of sys_call_table
    335	add	r8, r3
    336	mov.l	@r3, r8
    337	mov.l	@(OFF_R2,r15), r2
    338	mov.l	@(OFF_R1,r15), r1
    339	mov.l	@(OFF_R0,r15), r0
    340	mov.l	r2, @-r15
    341	mov.l	r1, @-r15
    342	mov.l	r0, @-r15
    343	jsr	@r8	    	! jump to specific syscall handler
    344	 nop
    345	add	#12, r15
    346	mov.l	@(OFF_R0,r15), r12		! save r0
    347	mov.l	r0, @(OFF_R0,r15)		! save the return value
    348	!
    349syscall_exit:
    350	cli
    351	TRACE_IRQS_OFF
    352	!
    353	get_current_thread_info r8, r0
    354	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
    355	tst	#(_TIF_ALLWORK_MASK & 0xff), r0
    356	mov	#(_TIF_ALLWORK_MASK >> 8), r1
    357	bf	syscall_exit_work
    358	shlr8	r0
    359	tst	r0, r1
    360	bf	syscall_exit_work
    361	bra	__restore_all
    362	 nop
    363
    364	.align	2
    365syscall_trace_entry:
    366	!                     	Yes it is traced.
    367	mov     r15, r4
    368	mov.l	7f, r11		! Call do_syscall_trace_enter which notifies
    369	jsr	@r11	    	! superior (will chomp R[0-7])
    370	 nop
    371	cmp/eq	#-1, r0
    372	bt	syscall_exit
    373	!			Reload R0-R4 from kernel stack, where the
    374	!   	    	    	parent may have modified them using
    375	!   	    	    	ptrace(POKEUSR).  (Note that R0-R2 are
    376	!   	    	    	reloaded from the kernel stack by syscall_call
    377	!   	    	    	below, so don't need to be reloaded here.)
    378	!   	    	    	This allows the parent to rewrite system calls
    379	!   	    	    	and args on the fly.
    380	mov.l	@(OFF_R4,r15), r4   ! arg0
    381	mov.l	@(OFF_R5,r15), r5
    382	mov.l	@(OFF_R6,r15), r6
    383	mov.l	@(OFF_R7,r15), r7   ! arg3
    384	mov.l	@(OFF_R3,r15), r3   ! syscall_nr
    385	!
    386	mov.l	6f, r10			! Number of syscalls
    387	cmp/hs	r10, r3
    388	bf	syscall_call
    389	mov	#-ENOSYS, r0
    390	bra	syscall_exit
    391	 mov.l	r0, @(OFF_R0,r15)	! Return value
    392
    393	.align	2
    394#if !defined(CONFIG_CPU_SH2)
    3951:	.long	TRA
    396#endif
    3976:	.long	NR_syscalls
    3983:	.long	sys_call_table
    3997:	.long	do_syscall_trace_enter
    4008:	.long	do_syscall_trace_leave