From: David S. Miller Date: Sun, 19 Feb 2006 00:39:39 +0000 (-0800) Subject: [SPARC64]: Fix unaligned access winfxup handling on SUN4V. X-Git-Tag: v2.6.17-rc1~1184^2~65 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24c523ecc667dfeb28ef969cfabc531709bfffb8;p=linux-2.6 [SPARC64]: Fix unaligned access winfxup handling on SUN4V. Another case where we have to force ourselves into global register level one. Also make sure the arguments passed to sun4v_do_mna() are correct. This area actually needs some more work, for example spill fixup is not necessarily going to do the right thing for this case. Signed-off-by: David S. Miller --- diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S index 57ccdaec7c..654244a3b0 100644 --- a/arch/sparc64/kernel/sun4v_tlb_miss.S +++ b/arch/sparc64/kernel/sun4v_tlb_miss.S @@ -137,7 +137,7 @@ sun4v_dtlb_load: sun4v_dtlb_prot: SET_GL(1) - /* Load MMU Miss base into %g2. */ + /* Load MMU Miss base into %g5. */ ldxa [%g0] ASI_SCRATCHPAD, %g5 ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5 @@ -148,9 +148,10 @@ sun4v_dtlb_prot: ba,pt %xcc, sparc64_realfault_common mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 - /* Called from trap table with TAG TARGET placed into - * %g6, SCRATCHPAD_UTSBREG1 contents in %g1, and - * SCRATCHPAD_MMU_MISS contents in %g2. + /* Called from trap table: + * %g4: vaddr + * %g5: context + * %g6: TAG TARGET */ sun4v_itsb_miss: mov SCRATCHPAD_UTSBREG1, %g1 @@ -159,8 +160,10 @@ sun4v_itsb_miss: mov FAULT_CODE_ITLB, %g3 ba,a,pt %xcc, sun4v_tsb_miss_common - /* Called from trap table with TAG TARGET placed into - * %g6 and SCRATCHPAD_UTSBREG1 contents in %g1. + /* Called from trap table: + * %g4: vaddr + * %g5: context + * %g6: TAG TARGET */ sun4v_dtsb_miss: mov SCRATCHPAD_UTSBREG1, %g1 @@ -168,6 +171,8 @@ sun4v_dtsb_miss: brz,pn %g5, kvmap_dtlb_4v mov FAULT_CODE_DTLB, %g3 + /* fallthrough */ + /* Create TSB pointer into %g1. This is something like: * * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL; @@ -304,19 +309,30 @@ sun4v_dacc_tl1: /* Memory Address Unaligned. */ sun4v_mna: - ldxa [%g0] ASI_SCRATCHPAD, %g2 + /* Window fixup? */ + rdpr %tl, %g2 + cmp %g2, 1 + ble,pt %icc, 1f + nop + + SET_GL(1) + ldxa [%g0] ASI_SCRATCHPAD, %g5 + ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5 + mov HV_FAULT_TYPE_UNALIGNED, %g3 + ldx [%g5 + HV_FAULT_D_CTX_OFFSET], %g4 + sllx %g3, 16, %g3 + or %g4, %g3, %g4 + ba,pt %xcc, winfix_mna + rdpr %tpc, %g3 + /* not reached */ + +1: ldxa [%g0] ASI_SCRATCHPAD, %g2 mov HV_FAULT_TYPE_UNALIGNED, %g3 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 sllx %g3, 16, %g3 or %g5, %g3, %g5 - /* Window fixup? */ - rdpr %tl, %g2 - cmp %g2, 1 - bgu,pn %icc, winfix_mna - rdpr %tpc, %g3 - ba,pt %xcc, etrap rd %pc, %g7 mov %l4, %o1 diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S index 161371370e..c4aa110a10 100644 --- a/arch/sparc64/kernel/winfixup.S +++ b/arch/sparc64/kernel/winfixup.S @@ -115,16 +115,17 @@ fill_fixup_mna: ba,pt %xcc, etrap rd %pc, %g7 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 + mov %l4, %o2 call sun4v_do_mna - nop + mov %l5, %o1 ba,a,pt %xcc, rtrap_clr_l6 -1: call mem_address_unaligned +1: mov %l4, %o1 + mov %l5, %o2 + call mem_address_unaligned nop ba,a,pt %xcc, rtrap_clr_l6