aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/signal32.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2005-08-29 15:46:22 -0400
committerDavid S. Miller <davem@davemloft.net>2005-08-29 15:46:22 -0400
commit4f07118f656c179740cad35b827032e2e29b1210 (patch)
tree7ddeb17346fe25ae75aa5373659c053afb9ef5f5 /arch/sparc64/kernel/signal32.c
parent442464a50077ff00454ff8d7628cbe1b8eacc034 (diff)
[SPARC64]: More fully work around Spitfire Errata 51.
It appears that a memory barrier soon after a mispredicted branch, not just in the delay slot, can cause the hang condition of this cpu errata. So move them out-of-line, and explicitly put them into a "branch always, predict taken" delay slot which should fully kill this problem. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/signal32.c')
-rw-r--r--arch/sparc64/kernel/signal32.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index b1ed23091fbb..aecccd0df1d1 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -877,11 +877,12 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
877 unsigned long page = (unsigned long) 877 unsigned long page = (unsigned long)
878 page_address(pte_page(*ptep)); 878 page_address(pte_page(*ptep));
879 879
880 __asm__ __volatile__( 880 wmb();
881 " membar #StoreStore\n" 881 __asm__ __volatile__("flush %0 + %1"
882 " flush %0 + %1" 882 : /* no outputs */
883 : : "r" (page), "r" (address & (PAGE_SIZE - 1)) 883 : "r" (page),
884 : "memory"); 884 "r" (address & (PAGE_SIZE - 1))
885 : "memory");
885 } 886 }
886 pte_unmap(ptep); 887 pte_unmap(ptep);
887 preempt_enable(); 888 preempt_enable();
@@ -1292,11 +1293,12 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
1292 unsigned long page = (unsigned long) 1293 unsigned long page = (unsigned long)
1293 page_address(pte_page(*ptep)); 1294 page_address(pte_page(*ptep));
1294 1295
1295 __asm__ __volatile__( 1296 wmb();
1296 " membar #StoreStore\n" 1297 __asm__ __volatile__("flush %0 + %1"
1297 " flush %0 + %1" 1298 : /* no outputs */
1298 : : "r" (page), "r" (address & (PAGE_SIZE - 1)) 1299 : "r" (page),
1299 : "memory"); 1300 "r" (address & (PAGE_SIZE - 1))
1301 : "memory");
1300 } 1302 }
1301 pte_unmap(ptep); 1303 pte_unmap(ptep);
1302 preempt_enable(); 1304 preempt_enable();