aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/gruhandles.c
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2009-12-15 19:48:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 10:20:15 -0500
commit67bf04a5c2574e9495f660f418f6df776821d578 (patch)
treeff28ab4983b007136da88786c8966ea1598841a0 /drivers/misc/sgi-gru/gruhandles.c
parente006043a4d2da52bba9fd9cb7e5a22e2951ff69b (diff)
gru: fix prefetch and speculation bugs
Fix several bugs related to prefetch, ordering & speculation: - GRU cch_allocate() instruction causes cacheable memory to be created. Add a barriers to prevent speculation from prefetching data before it exists. - Add memory barriers before cache-flush instructions to ensure that previously stored data is included in the line flushed to memory. Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-gru/gruhandles.c')
-rw-r--r--drivers/misc/sgi-gru/gruhandles.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
index 806419a6b44c..f1117a7637a2 100644
--- a/drivers/misc/sgi-gru/gruhandles.c
+++ b/drivers/misc/sgi-gru/gruhandles.c
@@ -91,9 +91,18 @@ static int wait_instruction_complete(void *h, enum mcs_op opc)
91 91
92int cch_allocate(struct gru_context_configuration_handle *cch) 92int cch_allocate(struct gru_context_configuration_handle *cch)
93{ 93{
94 int ret;
95
94 cch->opc = CCHOP_ALLOCATE; 96 cch->opc = CCHOP_ALLOCATE;
95 start_instruction(cch); 97 start_instruction(cch);
96 return wait_instruction_complete(cch, cchop_allocate); 98 ret = wait_instruction_complete(cch, cchop_allocate);
99
100 /*
101 * Stop speculation into the GSEG being mapped by the previous ALLOCATE.
102 * The GSEG memory does not exist until the ALLOCATE completes.
103 */
104 sync_core();
105 return ret;
97} 106}
98 107
99int cch_start(struct gru_context_configuration_handle *cch) 108int cch_start(struct gru_context_configuration_handle *cch)
@@ -112,9 +121,18 @@ int cch_interrupt(struct gru_context_configuration_handle *cch)
112 121
113int cch_deallocate(struct gru_context_configuration_handle *cch) 122int cch_deallocate(struct gru_context_configuration_handle *cch)
114{ 123{
124 int ret;
125
115 cch->opc = CCHOP_DEALLOCATE; 126 cch->opc = CCHOP_DEALLOCATE;
116 start_instruction(cch); 127 start_instruction(cch);
117 return wait_instruction_complete(cch, cchop_deallocate); 128 ret = wait_instruction_complete(cch, cchop_deallocate);
129
130 /*
131 * Stop speculation into the GSEG being unmapped by the previous
132 * DEALLOCATE.
133 */
134 sync_core();
135 return ret;
118} 136}
119 137
120int cch_interrupt_sync(struct gru_context_configuration_handle 138int cch_interrupt_sync(struct gru_context_configuration_handle