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

rtrap_32.S (5767B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * rtrap.S: Return from Sparc trap low-level code.
      4 *
      5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
      6 */
      7
      8#include <asm/page.h>
      9#include <asm/ptrace.h>
     10#include <asm/psr.h>
     11#include <asm/asi.h>
     12#include <asm/smp.h>
     13#include <asm/contregs.h>
     14#include <asm/winmacro.h>
     15#include <asm/asmmacro.h>
     16#include <asm/thread_info.h>
     17
     18#define t_psr     l0
     19#define t_pc      l1
     20#define t_npc     l2
     21#define t_wim     l3
     22#define twin_tmp1 l4
     23#define glob_tmp  g4
     24#define curptr    g6
     25
     26	/* 7 WINDOW SPARC PATCH INSTRUCTIONS */
     27	.globl	rtrap_7win_patch1, rtrap_7win_patch2, rtrap_7win_patch3
     28	.globl	rtrap_7win_patch4, rtrap_7win_patch5
     29rtrap_7win_patch1:	srl	%t_wim, 0x6, %glob_tmp
     30rtrap_7win_patch2:	and	%glob_tmp, 0x7f, %glob_tmp
     31rtrap_7win_patch3:	srl	%g1, 7, %g2
     32rtrap_7win_patch4:	srl	%g2, 6, %g2
     33rtrap_7win_patch5:	and	%g1, 0x7f, %g1
     34	/* END OF PATCH INSTRUCTIONS */
     35
     36	/* We need to check for a few things which are:
     37	 * 1) The need to call schedule() because this
     38	 *    processes quantum is up.
     39	 * 2) Pending signals for this process, if any
     40	 *    exist we need to call do_signal() to do
     41	 *    the needy.
     42	 *
     43	 * Else we just check if the rett would land us
     44	 * in an invalid window, if so we need to grab
     45	 * it off the user/kernel stack first.
     46	 */
     47
     48	.globl	ret_trap_entry, rtrap_patch1, rtrap_patch2
     49	.globl	rtrap_patch3, rtrap_patch4, rtrap_patch5
     50	.globl	ret_trap_lockless_ipi
     51ret_trap_entry:
     52ret_trap_lockless_ipi:
     53	andcc	%t_psr, PSR_PS, %g0
     54	sethi	%hi(PSR_SYSCALL), %g1
     55	be	1f
     56	 andn	%t_psr, %g1, %t_psr
     57
     58	wr	%t_psr, 0x0, %psr
     59	b	ret_trap_kernel
     60	 nop
     61
     621:
     63	ld	[%curptr + TI_FLAGS], %g2
     64	andcc	%g2, (_TIF_NEED_RESCHED), %g0
     65	be	signal_p
     66	 nop
     67
     68	call	schedule
     69	 nop
     70
     71	ld	[%curptr + TI_FLAGS], %g2
     72signal_p:
     73	andcc	%g2, _TIF_DO_NOTIFY_RESUME_MASK, %g0
     74	bz,a	ret_trap_continue
     75	 ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
     76
     77	mov	%g2, %o2
     78	mov	%l6, %o1
     79	call	do_notify_resume
     80	 add	%sp, STACKFRAME_SZ, %o0	! pt_regs ptr
     81
     82	b	signal_p
     83	 ld	[%curptr + TI_FLAGS], %g2
     84
     85ret_trap_continue:
     86	sethi	%hi(PSR_SYSCALL), %g1
     87	andn	%t_psr, %g1, %t_psr
     88	wr	%t_psr, 0x0, %psr
     89	WRITE_PAUSE
     90
     91	ld	[%curptr + TI_W_SAVED], %twin_tmp1
     92	orcc	%g0, %twin_tmp1, %g0
     93	be	ret_trap_nobufwins
     94	 nop
     95
     96	wr	%t_psr, PSR_ET, %psr
     97	WRITE_PAUSE
     98
     99	mov	1, %o1
    100	call	try_to_clear_window_buffer
    101	 add	%sp, STACKFRAME_SZ, %o0
    102
    103	b	signal_p
    104	 ld	[%curptr + TI_FLAGS], %g2
    105
    106ret_trap_nobufwins:
    107	/* Load up the user's out registers so we can pull
    108	 * a window from the stack, if necessary.
    109	 */
    110	LOAD_PT_INS(sp)
    111
    112	/* If there are already live user windows in the
    113	 * set we can return from trap safely.
    114	 */
    115	ld	[%curptr + TI_UWINMASK], %twin_tmp1
    116	orcc	%g0, %twin_tmp1, %g0
    117	bne	ret_trap_userwins_ok
    118	 nop
    119
    120		/* Calculate new %wim, we have to pull a register
    121		 * window from the users stack.
    122		 */
    123ret_trap_pull_one_window:
    124		rd	%wim, %t_wim
    125		sll	%t_wim, 0x1, %twin_tmp1
    126rtrap_patch1:	srl	%t_wim, 0x7, %glob_tmp
    127		or	%glob_tmp, %twin_tmp1, %glob_tmp
    128rtrap_patch2:	and	%glob_tmp, 0xff, %glob_tmp
    129
    130		wr	%glob_tmp, 0x0, %wim
    131
    132	/* Here comes the architecture specific
    133	 * branch to the user stack checking routine
    134	 * for return from traps.
    135	 */
    136	b	srmmu_rett_stackchk
    137	 andcc	%fp, 0x7, %g0
    138
    139ret_trap_userwins_ok:
    140	LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
    141	or	%t_pc, %t_npc, %g2
    142	andcc	%g2, 0x3, %g0
    143	sethi	%hi(PSR_SYSCALL), %g2
    144	be	1f
    145	 andn	%t_psr, %g2, %t_psr
    146
    147	b	ret_trap_unaligned_pc
    148	 add	%sp, STACKFRAME_SZ, %o0
    149
    1501:
    151	LOAD_PT_YREG(sp, g1)
    152	LOAD_PT_GLOBALS(sp)
    153
    154	wr	%t_psr, 0x0, %psr
    155	WRITE_PAUSE
    156
    157	jmp	%t_pc
    158	rett	%t_npc
    159	
    160ret_trap_unaligned_pc:
    161	ld	[%sp + STACKFRAME_SZ + PT_PC], %o1
    162	ld	[%sp + STACKFRAME_SZ + PT_NPC], %o2
    163	ld	[%sp + STACKFRAME_SZ + PT_PSR], %o3
    164
    165	wr	%t_wim, 0x0, %wim		! or else...
    166
    167	wr	%t_psr, PSR_ET, %psr
    168	WRITE_PAUSE
    169
    170	call	do_memaccess_unaligned
    171	 nop
    172
    173	b	signal_p
    174	 ld	[%curptr + TI_FLAGS], %g2
    175
    176ret_trap_kernel:
    177		/* Will the rett land us in the invalid window? */
    178		mov	2, %g1
    179		sll	%g1, %t_psr, %g1
    180rtrap_patch3:	srl	%g1, 8, %g2
    181		or	%g1, %g2, %g1
    182		rd	%wim, %g2
    183		andcc	%g2, %g1, %g0
    184		be	1f		! Nope, just return from the trap
    185		 sll	%g2, 0x1, %g1
    186
    187		/* We have to grab a window before returning. */
    188rtrap_patch4:	srl	%g2, 7,  %g2
    189		or	%g1, %g2, %g1
    190rtrap_patch5:	and	%g1, 0xff, %g1
    191
    192	wr	%g1, 0x0, %wim
    193
    194	/* Grrr, make sure we load from the right %sp... */
    195	LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
    196
    197	restore	%g0, %g0, %g0
    198	LOAD_WINDOW(sp)
    199	b	2f
    200	 save	%g0, %g0, %g0
    201
    202	/* Reload the entire frame in case this is from a
    203	 * kernel system call or whatever...
    204	 */
    2051:
    206	LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
    2072:
    208	sethi	%hi(PSR_SYSCALL), %twin_tmp1
    209	andn	%t_psr, %twin_tmp1, %t_psr
    210	wr	%t_psr, 0x0, %psr
    211	WRITE_PAUSE
    212
    213	jmp	%t_pc
    214	rett	%t_npc
    215
    216ret_trap_user_stack_is_bolixed:
    217	wr	%t_wim, 0x0, %wim
    218
    219	wr	%t_psr, PSR_ET, %psr
    220	WRITE_PAUSE
    221
    222	call	window_ret_fault
    223	 add	%sp, STACKFRAME_SZ, %o0
    224
    225	b	signal_p
    226	 ld	[%curptr + TI_FLAGS], %g2
    227
    228	.globl	srmmu_rett_stackchk
    229srmmu_rett_stackchk:
    230	bne	ret_trap_user_stack_is_bolixed
    231	 sethi   %hi(PAGE_OFFSET), %g1
    232	cmp	%g1, %fp
    233	bleu	ret_trap_user_stack_is_bolixed
    234	 mov	AC_M_SFSR, %g1
    235LEON_PI(lda	[%g1] ASI_LEON_MMUREGS, %g0)
    236SUN_PI_(lda	[%g1] ASI_M_MMUREGS, %g0)
    237
    238LEON_PI(lda	[%g0] ASI_LEON_MMUREGS, %g1)
    239SUN_PI_(lda	[%g0] ASI_M_MMUREGS, %g1)
    240	or	%g1, 0x2, %g1
    241LEON_PI(sta	%g1, [%g0] ASI_LEON_MMUREGS)
    242SUN_PI_(sta	%g1, [%g0] ASI_M_MMUREGS)
    243
    244	restore	%g0, %g0, %g0
    245
    246	LOAD_WINDOW(sp)
    247
    248	save	%g0, %g0, %g0
    249
    250	andn	%g1, 0x2, %g1
    251LEON_PI(sta	%g1, [%g0] ASI_LEON_MMUREGS)
    252SUN_PI_(sta	%g1, [%g0] ASI_M_MMUREGS)
    253
    254	mov	AC_M_SFAR, %g2
    255LEON_PI(lda	[%g2] ASI_LEON_MMUREGS, %g2)
    256SUN_PI_(lda	[%g2] ASI_M_MMUREGS, %g2)
    257
    258	mov	AC_M_SFSR, %g1
    259LEON_PI(lda	[%g1] ASI_LEON_MMUREGS, %g1)
    260SUN_PI_(lda	[%g1] ASI_M_MMUREGS, %g1)
    261	andcc	%g1, 0x2, %g0
    262	be	ret_trap_userwins_ok
    263	 nop
    264
    265	b,a	ret_trap_user_stack_is_bolixed