/* SPDX-License-Identifier: GPL-2.0 */
#include <asm/thread_info.h>
#include <asm/trap_block.h>
#include <asm/spitfire.h>
#include <asm/ptrace.h>
#include <asm/head.h>
.text
.align 8
.globl user_rtt_fill_fixup_common
user_rtt_fill_fixup_common:
rdpr %cwp, %g1
add %g1, 1, %g1
wrpr %g1, 0x0, %cwp
rdpr %wstate, %g2
sll %g2, 3, %g2
wrpr %g2, 0x0, %wstate
/* We know %canrestore and %otherwin are both zero. */
sethi %hi(sparc64_kern_pri_context), %g2
ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
mov PRIMARY_CONTEXT, %g1
661: stxa %g2, [%g1] ASI_DMMU
.section .sun4v_1insn_patch, "ax"
.word 661b
stxa %g2, [%g1] ASI_MMU
.previous
sethi %hi(KERNBASE), %g1
flush %g1
mov %g4, %l4
mov %g5, %l5
brnz,pn %g3, 1f
mov %g3, %l3
or %g4, FAULT_CODE_WINFIXUP, %g4
stb %g4, [%g6 + TI_FAULT_CODE]
stx %g5, [%g6 + TI_FAULT_ADDR]
1:
mov %g6, %l1
wrpr %g0, 0x0, %tl
661: nop
.section .sun4v_1insn_patch, "ax"
.word 661b
SET_GL(0)
.previous
661: wrpr %g0, RTRAP_PSTATE, %pstate
.section .sun_m7_1insn_patch, "ax"
.word 661b
/* Re-enable PSTATE.mcde to maintain ADI security */
wrpr %g0, RTRAP_PSTATE|PSTATE_MCDE, %pstate
.previous
mov %l1, %g6
ldx [%g6 + TI_TASK], %g4
LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
brnz,pn %l3, 1f
nop
call do_sparc64_fault
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
1: cmp %g3, 2
bne,pn %xcc, 2f
nop
sethi %hi(tlb_type), %g1
lduw [%g1 + %lo(tlb_type)], %g1
cmp %g1, 3
bne,pt %icc, 1f
add %sp, PTREGS_OFF, %o0
mov %l4, %o2
call sun4v_do_mna
mov %l5, %o1
ba,a,pt %xcc, rtrap
1: mov %l4, %o1
mov %l5, %o2
call mem_address_unaligned
nop
ba,a,pt %xcc, rtrap
2: sethi %hi(tlb_type), %g1
mov %l4, %o1
lduw [%g1 + %lo(tlb_type)], %g1
mov %l5, %o2
cmp %g1, 3
bne,pt %icc, 1f
add %sp, PTREGS_OFF, %o0
call sun4v_data_access_exception
nop
ba,a,pt %xcc, rtrap
nop
1: call spitfire_data_access_exception
nop
ba,a,pt %xcc, rtrap