[SPARC64]: Fix userland FPU state corruption.

We need to use stricter memory barriers around the block
load and store instructions we use to save and restore the
FPU register file.

Signed-off-by: David S. Miller <davem@davemloft.net>

+30 -24
+21 -18
arch/sparc64/kernel/entry.S
··· 33 /* This is trivial with the new code... */ 34 .globl do_fpdis 35 do_fpdis: 36 - sethi %hi(TSTATE_PEF), %g4 ! IEU0 37 rdpr %tstate, %g5 38 andcc %g5, %g4, %g0 39 be,pt %xcc, 1f ··· 50 add %g0, %g0, %g0 51 ba,a,pt %xcc, rtrap_clr_l6 52 53 - 1: ldub [%g6 + TI_FPSAVED], %g5 ! Load Group 54 - wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles 55 - andcc %g5, FPRS_FEF, %g0 ! IEU1 Group 56 - be,a,pt %icc, 1f ! CTI 57 - clr %g7 ! IEU0 58 - ldx [%g6 + TI_GSR], %g7 ! Load Group 59 - 1: andcc %g5, FPRS_DL, %g0 ! IEU1 60 - bne,pn %icc, 2f ! CTI 61 - fzero %f0 ! FPA 62 - andcc %g5, FPRS_DU, %g0 ! IEU1 Group 63 - bne,pn %icc, 1f ! CTI 64 - fzero %f2 ! FPA 65 faddd %f0, %f2, %f4 66 fmuld %f0, %f2, %f6 67 faddd %f0, %f2, %f8 ··· 104 add %g6, TI_FPREGS + 0xc0, %g2 105 faddd %f0, %f2, %f8 106 fmuld %f0, %f2, %f10 107 - ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-( 108 ldda [%g2] ASI_BLK_S, %f48 109 faddd %f0, %f2, %f12 110 fmuld %f0, %f2, %f14 111 faddd %f0, %f2, %f16 ··· 118 fmuld %f0, %f2, %f26 119 faddd %f0, %f2, %f28 120 fmuld %f0, %f2, %f30 121 - membar #Sync 122 b,pt %xcc, fpdis_exit 123 nop 124 2: andcc %g5, FPRS_DU, %g0 ··· 134 add %g6, TI_FPREGS + 0x40, %g2 135 faddd %f32, %f34, %f36 136 fmuld %f32, %f34, %f38 137 - ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( 138 ldda [%g2] ASI_BLK_S, %f16 139 faddd %f32, %f34, %f40 140 fmuld %f32, %f34, %f42 141 faddd %f32, %f34, %f44 ··· 150 fmuld %f32, %f34, %f58 151 faddd %f32, %f34, %f60 152 fmuld %f32, %f34, %f62 153 - membar #Sync 154 ba,pt %xcc, fpdis_exit 155 nop 156 3: mov SECONDARY_CONTEXT, %g3 ··· 160 stxa %g2, [%g3] ASI_DMMU 161 membar #Sync 162 mov 0x40, %g2 163 - ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( 164 ldda [%g1 + %g2] ASI_BLK_S, %f16 165 add %g1, 0x80, %g1 166 ldda [%g1] ASI_BLK_S, %f32
··· 33 /* This is trivial with the new code... */ 34 .globl do_fpdis 35 do_fpdis: 36 + sethi %hi(TSTATE_PEF), %g4 37 rdpr %tstate, %g5 38 andcc %g5, %g4, %g0 39 be,pt %xcc, 1f ··· 50 add %g0, %g0, %g0 51 ba,a,pt %xcc, rtrap_clr_l6 52 53 + 1: ldub [%g6 + TI_FPSAVED], %g5 54 + wr %g0, FPRS_FEF, %fprs 55 + andcc %g5, FPRS_FEF, %g0 56 + be,a,pt %icc, 1f 57 + clr %g7 58 + ldx [%g6 + TI_GSR], %g7 59 + 1: andcc %g5, FPRS_DL, %g0 60 + bne,pn %icc, 2f 61 + fzero %f0 62 + andcc %g5, FPRS_DU, %g0 63 + bne,pn %icc, 1f 64 + fzero %f2 65 faddd %f0, %f2, %f4 66 fmuld %f0, %f2, %f6 67 faddd %f0, %f2, %f8 ··· 104 add %g6, TI_FPREGS + 0xc0, %g2 105 faddd %f0, %f2, %f8 106 fmuld %f0, %f2, %f10 107 + membar #Sync 108 + ldda [%g1] ASI_BLK_S, %f32 109 ldda [%g2] ASI_BLK_S, %f48 110 + membar #Sync 111 faddd %f0, %f2, %f12 112 fmuld %f0, %f2, %f14 113 faddd %f0, %f2, %f16 ··· 116 fmuld %f0, %f2, %f26 117 faddd %f0, %f2, %f28 118 fmuld %f0, %f2, %f30 119 b,pt %xcc, fpdis_exit 120 nop 121 2: andcc %g5, FPRS_DU, %g0 ··· 133 add %g6, TI_FPREGS + 0x40, %g2 134 faddd %f32, %f34, %f36 135 fmuld %f32, %f34, %f38 136 + membar #Sync 137 + ldda [%g1] ASI_BLK_S, %f0 138 ldda [%g2] ASI_BLK_S, %f16 139 + membar #Sync 140 faddd %f32, %f34, %f40 141 fmuld %f32, %f34, %f42 142 faddd %f32, %f34, %f44 ··· 147 fmuld %f32, %f34, %f58 148 faddd %f32, %f34, %f60 149 fmuld %f32, %f34, %f62 150 ba,pt %xcc, fpdis_exit 151 nop 152 3: mov SECONDARY_CONTEXT, %g3 ··· 158 stxa %g2, [%g3] ASI_DMMU 159 membar #Sync 160 mov 0x40, %g2 161 + membar #Sync 162 + ldda [%g1] ASI_BLK_S, %f0 163 ldda [%g1 + %g2] ASI_BLK_S, %f16 164 add %g1, 0x80, %g1 165 ldda [%g1] ASI_BLK_S, %f32
+4 -3
arch/sparc64/kernel/rtrap.S
··· 312 wr %g1, FPRS_FEF, %fprs 313 ldx [%o1 + %o5], %g1 314 add %g6, TI_XFSR, %o1 315 - membar #StoreLoad | #LoadLoad 316 sll %o0, 8, %o2 317 add %g6, TI_FPREGS, %o3 318 brz,pn %l6, 1f 319 add %g6, TI_FPREGS+0x40, %o4 320 321 ldda [%o3 + %o2] ASI_BLK_P, %f0 322 ldda [%o4 + %o2] ASI_BLK_P, %f16 323 1: andcc %l2, FPRS_DU, %g0 324 be,pn %icc, 1f 325 wr %g1, 0, %gsr 326 add %o2, 0x80, %o2 327 ldda [%o3 + %o2] ASI_BLK_P, %f32 328 ldda [%o4 + %o2] ASI_BLK_P, %f48 329 - 330 1: membar #Sync 331 ldx [%o1 + %o5], %fsr 332 2: stb %l5, [%g6 + TI_FPDEPTH] 333 ba,pt %xcc, rt_continue 334 nop 335 5: wr %g0, FPRS_FEF, %fprs 336 - membar #StoreLoad | #LoadLoad 337 sll %o0, 8, %o2 338 339 add %g6, TI_FPREGS+0x80, %o3 340 add %g6, TI_FPREGS+0xc0, %o4 341 ldda [%o3 + %o2] ASI_BLK_P, %f32 342 ldda [%o4 + %o2] ASI_BLK_P, %f48 343 membar #Sync
··· 312 wr %g1, FPRS_FEF, %fprs 313 ldx [%o1 + %o5], %g1 314 add %g6, TI_XFSR, %o1 315 sll %o0, 8, %o2 316 add %g6, TI_FPREGS, %o3 317 brz,pn %l6, 1f 318 add %g6, TI_FPREGS+0x40, %o4 319 320 + membar #Sync 321 ldda [%o3 + %o2] ASI_BLK_P, %f0 322 ldda [%o4 + %o2] ASI_BLK_P, %f16 323 + membar #Sync 324 1: andcc %l2, FPRS_DU, %g0 325 be,pn %icc, 1f 326 wr %g1, 0, %gsr 327 add %o2, 0x80, %o2 328 + membar #Sync 329 ldda [%o3 + %o2] ASI_BLK_P, %f32 330 ldda [%o4 + %o2] ASI_BLK_P, %f48 331 1: membar #Sync 332 ldx [%o1 + %o5], %fsr 333 2: stb %l5, [%g6 + TI_FPDEPTH] 334 ba,pt %xcc, rt_continue 335 nop 336 5: wr %g0, FPRS_FEF, %fprs 337 sll %o0, 8, %o2 338 339 add %g6, TI_FPREGS+0x80, %o3 340 add %g6, TI_FPREGS+0xc0, %o4 341 + membar #Sync 342 ldda [%o3 + %o2] ASI_BLK_P, %f32 343 ldda [%o4 + %o2] ASI_BLK_P, %f48 344 membar #Sync
+5 -3
arch/sparc64/lib/VISsave.S
··· 59 be,pn %icc, 9b 60 add %g6, TI_FPREGS, %g2 61 andcc %o5, FPRS_DL, %g0 62 - membar #StoreStore | #LoadStore 63 64 be,pn %icc, 4f 65 add %g6, TI_FPREGS+0x40, %g3 66 stda %f0, [%g2 + %g1] ASI_BLK_P 67 stda %f16, [%g3 + %g1] ASI_BLK_P 68 andcc %o5, FPRS_DU, %g0 69 be,pn %icc, 5f 70 4: add %g1, 128, %g1 71 stda %f32, [%g2 + %g1] ASI_BLK_P 72 73 stda %f48, [%g3 + %g1] ASI_BLK_P ··· 89 sll %g1, 5, %g1 90 add %g6, TI_FPREGS+0xc0, %g3 91 wr %g0, FPRS_FEF, %fprs 92 - membar #StoreStore | #LoadStore 93 stda %f32, [%g2 + %g1] ASI_BLK_P 94 stda %f48, [%g3 + %g1] ASI_BLK_P 95 membar #Sync ··· 130 be,pn %icc, 4f 131 add %g6, TI_FPREGS, %g2 132 133 - membar #StoreStore | #LoadStore 134 add %g6, TI_FPREGS+0x40, %g3 135 stda %f0, [%g2 + %g1] ASI_BLK_P 136 stda %f16, [%g3 + %g1] ASI_BLK_P 137 membar #Sync
··· 59 be,pn %icc, 9b 60 add %g6, TI_FPREGS, %g2 61 andcc %o5, FPRS_DL, %g0 62 63 be,pn %icc, 4f 64 add %g6, TI_FPREGS+0x40, %g3 65 + membar #Sync 66 stda %f0, [%g2 + %g1] ASI_BLK_P 67 stda %f16, [%g3 + %g1] ASI_BLK_P 68 + membar #Sync 69 andcc %o5, FPRS_DU, %g0 70 be,pn %icc, 5f 71 4: add %g1, 128, %g1 72 + membar #Sync 73 stda %f32, [%g2 + %g1] ASI_BLK_P 74 75 stda %f48, [%g3 + %g1] ASI_BLK_P ··· 87 sll %g1, 5, %g1 88 add %g6, TI_FPREGS+0xc0, %g3 89 wr %g0, FPRS_FEF, %fprs 90 + membar #Sync 91 stda %f32, [%g2 + %g1] ASI_BLK_P 92 stda %f48, [%g3 + %g1] ASI_BLK_P 93 membar #Sync ··· 128 be,pn %icc, 4f 129 add %g6, TI_FPREGS, %g2 130 131 add %g6, TI_FPREGS+0x40, %g3 132 + membar #Sync 133 stda %f0, [%g2 + %g1] ASI_BLK_P 134 stda %f16, [%g3 + %g1] ASI_BLK_P 135 membar #Sync