Commit d7c6ec0f authored by David S. Miller's avatar David S. Miller Committed by Greg Kroah-Hartman

[PATCH] 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: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarChris Wright <chrisw@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 1aa561c7
...@@ -186,7 +186,7 @@ vmalloc_addr: ...@@ -186,7 +186,7 @@ vmalloc_addr:
/* This is trivial with the new code... */ /* This is trivial with the new code... */
.globl do_fpdis .globl do_fpdis
do_fpdis: do_fpdis:
sethi %hi(TSTATE_PEF), %g4 ! IEU0 sethi %hi(TSTATE_PEF), %g4
rdpr %tstate, %g5 rdpr %tstate, %g5
andcc %g5, %g4, %g0 andcc %g5, %g4, %g0
be,pt %xcc, 1f be,pt %xcc, 1f
...@@ -203,18 +203,18 @@ do_fpdis: ...@@ -203,18 +203,18 @@ do_fpdis:
add %g0, %g0, %g0 add %g0, %g0, %g0
ba,a,pt %xcc, rtrap_clr_l6 ba,a,pt %xcc, rtrap_clr_l6
1: ldub [%g6 + TI_FPSAVED], %g5 ! Load Group 1: ldub [%g6 + TI_FPSAVED], %g5
wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles wr %g0, FPRS_FEF, %fprs
andcc %g5, FPRS_FEF, %g0 ! IEU1 Group andcc %g5, FPRS_FEF, %g0
be,a,pt %icc, 1f ! CTI be,a,pt %icc, 1f
clr %g7 ! IEU0 clr %g7
ldx [%g6 + TI_GSR], %g7 ! Load Group ldx [%g6 + TI_GSR], %g7
1: andcc %g5, FPRS_DL, %g0 ! IEU1 1: andcc %g5, FPRS_DL, %g0
bne,pn %icc, 2f ! CTI bne,pn %icc, 2f
fzero %f0 ! FPA fzero %f0
andcc %g5, FPRS_DU, %g0 ! IEU1 Group andcc %g5, FPRS_DU, %g0
bne,pn %icc, 1f ! CTI bne,pn %icc, 1f
fzero %f2 ! FPA fzero %f2
faddd %f0, %f2, %f4 faddd %f0, %f2, %f4
fmuld %f0, %f2, %f6 fmuld %f0, %f2, %f6
faddd %f0, %f2, %f8 faddd %f0, %f2, %f8
...@@ -257,8 +257,10 @@ cplus_fptrap_insn_1: ...@@ -257,8 +257,10 @@ cplus_fptrap_insn_1:
add %g6, TI_FPREGS + 0xc0, %g2 add %g6, TI_FPREGS + 0xc0, %g2
faddd %f0, %f2, %f8 faddd %f0, %f2, %f8
fmuld %f0, %f2, %f10 fmuld %f0, %f2, %f10
ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-( membar #Sync
ldda [%g1] ASI_BLK_S, %f32
ldda [%g2] ASI_BLK_S, %f48 ldda [%g2] ASI_BLK_S, %f48
membar #Sync
faddd %f0, %f2, %f12 faddd %f0, %f2, %f12
fmuld %f0, %f2, %f14 fmuld %f0, %f2, %f14
faddd %f0, %f2, %f16 faddd %f0, %f2, %f16
...@@ -269,7 +271,6 @@ cplus_fptrap_insn_1: ...@@ -269,7 +271,6 @@ cplus_fptrap_insn_1:
fmuld %f0, %f2, %f26 fmuld %f0, %f2, %f26
faddd %f0, %f2, %f28 faddd %f0, %f2, %f28
fmuld %f0, %f2, %f30 fmuld %f0, %f2, %f30
membar #Sync
b,pt %xcc, fpdis_exit b,pt %xcc, fpdis_exit
nop nop
2: andcc %g5, FPRS_DU, %g0 2: andcc %g5, FPRS_DU, %g0
...@@ -286,8 +287,10 @@ cplus_fptrap_insn_2: ...@@ -286,8 +287,10 @@ cplus_fptrap_insn_2:
add %g6, TI_FPREGS + 0x40, %g2 add %g6, TI_FPREGS + 0x40, %g2
faddd %f32, %f34, %f36 faddd %f32, %f34, %f36
fmuld %f32, %f34, %f38 fmuld %f32, %f34, %f38
ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( membar #Sync
ldda [%g1] ASI_BLK_S, %f0
ldda [%g2] ASI_BLK_S, %f16 ldda [%g2] ASI_BLK_S, %f16
membar #Sync
faddd %f32, %f34, %f40 faddd %f32, %f34, %f40
fmuld %f32, %f34, %f42 fmuld %f32, %f34, %f42
faddd %f32, %f34, %f44 faddd %f32, %f34, %f44
...@@ -300,7 +303,6 @@ cplus_fptrap_insn_2: ...@@ -300,7 +303,6 @@ cplus_fptrap_insn_2:
fmuld %f32, %f34, %f58 fmuld %f32, %f34, %f58
faddd %f32, %f34, %f60 faddd %f32, %f34, %f60
fmuld %f32, %f34, %f62 fmuld %f32, %f34, %f62
membar #Sync
ba,pt %xcc, fpdis_exit ba,pt %xcc, fpdis_exit
nop nop
3: mov SECONDARY_CONTEXT, %g3 3: mov SECONDARY_CONTEXT, %g3
...@@ -311,7 +313,8 @@ cplus_fptrap_insn_3: ...@@ -311,7 +313,8 @@ cplus_fptrap_insn_3:
stxa %g2, [%g3] ASI_DMMU stxa %g2, [%g3] ASI_DMMU
membar #Sync membar #Sync
mov 0x40, %g2 mov 0x40, %g2
ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( membar #Sync
ldda [%g1] ASI_BLK_S, %f0
ldda [%g1 + %g2] ASI_BLK_S, %f16 ldda [%g1 + %g2] ASI_BLK_S, %f16
add %g1, 0x80, %g1 add %g1, 0x80, %g1
ldda [%g1] ASI_BLK_S, %f32 ldda [%g1] ASI_BLK_S, %f32
......
...@@ -310,32 +310,33 @@ kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5 ...@@ -310,32 +310,33 @@ kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5
wr %g1, FPRS_FEF, %fprs wr %g1, FPRS_FEF, %fprs
ldx [%o1 + %o5], %g1 ldx [%o1 + %o5], %g1
add %g6, TI_XFSR, %o1 add %g6, TI_XFSR, %o1
membar #StoreLoad | #LoadLoad
sll %o0, 8, %o2 sll %o0, 8, %o2
add %g6, TI_FPREGS, %o3 add %g6, TI_FPREGS, %o3
brz,pn %l6, 1f brz,pn %l6, 1f
add %g6, TI_FPREGS+0x40, %o4 add %g6, TI_FPREGS+0x40, %o4
membar #Sync
ldda [%o3 + %o2] ASI_BLK_P, %f0 ldda [%o3 + %o2] ASI_BLK_P, %f0
ldda [%o4 + %o2] ASI_BLK_P, %f16 ldda [%o4 + %o2] ASI_BLK_P, %f16
membar #Sync
1: andcc %l2, FPRS_DU, %g0 1: andcc %l2, FPRS_DU, %g0
be,pn %icc, 1f be,pn %icc, 1f
wr %g1, 0, %gsr wr %g1, 0, %gsr
add %o2, 0x80, %o2 add %o2, 0x80, %o2
membar #Sync
ldda [%o3 + %o2] ASI_BLK_P, %f32 ldda [%o3 + %o2] ASI_BLK_P, %f32
ldda [%o4 + %o2] ASI_BLK_P, %f48 ldda [%o4 + %o2] ASI_BLK_P, %f48
1: membar #Sync 1: membar #Sync
ldx [%o1 + %o5], %fsr ldx [%o1 + %o5], %fsr
2: stb %l5, [%g6 + TI_FPDEPTH] 2: stb %l5, [%g6 + TI_FPDEPTH]
ba,pt %xcc, rt_continue ba,pt %xcc, rt_continue
nop nop
5: wr %g0, FPRS_FEF, %fprs 5: wr %g0, FPRS_FEF, %fprs
membar #StoreLoad | #LoadLoad
sll %o0, 8, %o2 sll %o0, 8, %o2
add %g6, TI_FPREGS+0x80, %o3 add %g6, TI_FPREGS+0x80, %o3
add %g6, TI_FPREGS+0xc0, %o4 add %g6, TI_FPREGS+0xc0, %o4
membar #Sync
ldda [%o3 + %o2] ASI_BLK_P, %f32 ldda [%o3 + %o2] ASI_BLK_P, %f32
ldda [%o4 + %o2] ASI_BLK_P, %f48 ldda [%o4 + %o2] ASI_BLK_P, %f48
membar #Sync membar #Sync
......
...@@ -59,15 +59,17 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 ...@@ -59,15 +59,17 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3
be,pn %icc, 9b be,pn %icc, 9b
add %g6, TI_FPREGS, %g2 add %g6, TI_FPREGS, %g2
andcc %o5, FPRS_DL, %g0 andcc %o5, FPRS_DL, %g0
membar #StoreStore | #LoadStore
be,pn %icc, 4f be,pn %icc, 4f
add %g6, TI_FPREGS+0x40, %g3 add %g6, TI_FPREGS+0x40, %g3
membar #Sync
stda %f0, [%g2 + %g1] ASI_BLK_P stda %f0, [%g2 + %g1] ASI_BLK_P
stda %f16, [%g3 + %g1] ASI_BLK_P stda %f16, [%g3 + %g1] ASI_BLK_P
membar #Sync
andcc %o5, FPRS_DU, %g0 andcc %o5, FPRS_DU, %g0
be,pn %icc, 5f be,pn %icc, 5f
4: add %g1, 128, %g1 4: add %g1, 128, %g1
membar #Sync
stda %f32, [%g2 + %g1] ASI_BLK_P stda %f32, [%g2 + %g1] ASI_BLK_P
stda %f48, [%g3 + %g1] ASI_BLK_P stda %f48, [%g3 + %g1] ASI_BLK_P
...@@ -87,7 +89,7 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 ...@@ -87,7 +89,7 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3
sll %g1, 5, %g1 sll %g1, 5, %g1
add %g6, TI_FPREGS+0xc0, %g3 add %g6, TI_FPREGS+0xc0, %g3
wr %g0, FPRS_FEF, %fprs wr %g0, FPRS_FEF, %fprs
membar #StoreStore | #LoadStore membar #Sync
stda %f32, [%g2 + %g1] ASI_BLK_P stda %f32, [%g2 + %g1] ASI_BLK_P
stda %f48, [%g3 + %g1] ASI_BLK_P stda %f48, [%g3 + %g1] ASI_BLK_P
membar #Sync membar #Sync
...@@ -128,8 +130,8 @@ VISenterhalf: ...@@ -128,8 +130,8 @@ VISenterhalf:
be,pn %icc, 4f be,pn %icc, 4f
add %g6, TI_FPREGS, %g2 add %g6, TI_FPREGS, %g2
membar #StoreStore | #LoadStore
add %g6, TI_FPREGS+0x40, %g3 add %g6, TI_FPREGS+0x40, %g3
membar #Sync
stda %f0, [%g2 + %g1] ASI_BLK_P stda %f0, [%g2 + %g1] ASI_BLK_P
stda %f16, [%g3 + %g1] ASI_BLK_P stda %f16, [%g3 + %g1] ASI_BLK_P
membar #Sync membar #Sync
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment