[SPARC64]: Fix unaligned access winfxup handling on SUN4V.
David S. Miller [Sun, 19 Feb 2006 00:39:39 +0000 (16:39 -0800)]
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 <davem@davemloft.net>

arch/sparc64/kernel/sun4v_tlb_miss.S
arch/sparc64/kernel/winfixup.S

index 57ccdae..654244a 100644 (file)
@@ -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
index 1613713..c4aa110 100644 (file)
@@ -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