[SPARC64]: Refine register window trap handling.
When saving and restoing trap state, do the window spill/fill handling inline so that we never trap deeper than 2 trap levels. This is important for chips like Niagara. The window fixup code is massively simplified, and many more improvements are now possible. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -267,15 +267,69 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
|
||||
|
||||
wrpr %l2, %g0, %canrestore
|
||||
wrpr %l1, %g0, %wstate
|
||||
wrpr %g0, %g0, %otherwin
|
||||
brnz,pt %l2, user_rtt_restore
|
||||
wrpr %g0, %g0, %otherwin
|
||||
|
||||
ldx [%g6 + TI_FLAGS], %g3
|
||||
wr %g0, ASI_AIUP, %asi
|
||||
rdpr %cwp, %g1
|
||||
andcc %g3, _TIF_32BIT, %g0
|
||||
sub %g1, 1, %g1
|
||||
bne,pt %xcc, user_rtt_fill_32bit
|
||||
wrpr %g1, %cwp
|
||||
ba,a,pt %xcc, user_rtt_fill_64bit
|
||||
|
||||
user_rtt_fill_fixup:
|
||||
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
|
||||
stxa %g2, [%g1] ASI_DMMU
|
||||
sethi %hi(KERNBASE), %g1
|
||||
flush %g1
|
||||
|
||||
or %g4, FAULT_CODE_WINFIXUP, %g4
|
||||
stb %g4, [%g6 + TI_FAULT_CODE]
|
||||
stx %g5, [%g6 + TI_FAULT_ADDR]
|
||||
|
||||
mov %g6, %l1
|
||||
wrpr %g0, 0x0, %tl
|
||||
wrpr %g0, RTRAP_PSTATE, %pstate
|
||||
mov %l1, %g6
|
||||
ldx [%g6 + TI_TASK], %g4
|
||||
LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
|
||||
call do_sparc64_fault
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
|
||||
user_rtt_pre_restore:
|
||||
add %g1, 1, %g1
|
||||
wrpr %g1, 0x0, %cwp
|
||||
|
||||
user_rtt_restore:
|
||||
restore
|
||||
rdpr %canrestore, %g1
|
||||
wrpr %g1, 0x0, %cleanwin
|
||||
retry
|
||||
nop
|
||||
|
||||
kern_rtt: restore
|
||||
kern_rtt: rdpr %canrestore, %g1
|
||||
brz,pn %g1, kern_rtt_fill
|
||||
nop
|
||||
kern_rtt_restore:
|
||||
restore
|
||||
retry
|
||||
|
||||
to_kernel:
|
||||
#ifdef CONFIG_PREEMPT
|
||||
ldsw [%g6 + TI_PRE_COUNT], %l5
|
||||
|
Reference in New Issue
Block a user