Commit 195f7fd0a7e2b3179d52aa8ed6de3637203946c6
1 parent
848c4dd515
Exists in
master
and in
7 other branches
[SPARC64]: Need to clobber global reg vars in switch_to().
Otherwise the compiler can't see the things like the per-cpu area base register are changing. Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files with 15 additions and 15 deletions Side-by-side Diff
include/asm-sparc64/percpu.h
... | ... | @@ -3,6 +3,8 @@ |
3 | 3 | |
4 | 4 | #include <linux/compiler.h> |
5 | 5 | |
6 | +register unsigned long __local_per_cpu_offset asm("g5"); | |
7 | + | |
6 | 8 | #ifdef CONFIG_SMP |
7 | 9 | |
8 | 10 | #define setup_per_cpu_areas() do { } while (0) |
... | ... | @@ -22,8 +24,6 @@ |
22 | 24 | __attribute__((__section__(".data.percpu.shared_aligned"))) \ |
23 | 25 | __typeof__(type) per_cpu__##name \ |
24 | 26 | ____cacheline_aligned_in_smp |
25 | - | |
26 | -register unsigned long __local_per_cpu_offset asm("g5"); | |
27 | 27 | |
28 | 28 | /* var is in discarded region: offset to particular copy we want */ |
29 | 29 | #define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) |
include/asm-sparc64/system.h
... | ... | @@ -141,7 +141,6 @@ |
141 | 141 | * not preserve it's value. Hairy, but it lets us remove 2 loads |
142 | 142 | * and 2 stores in this critical code path. -DaveM |
143 | 143 | */ |
144 | -#define EXTRA_CLOBBER ,"%l1" | |
145 | 144 | #define switch_to(prev, next, last) \ |
146 | 145 | do { if (test_thread_flag(TIF_PERFCTR)) { \ |
147 | 146 | unsigned long __tmp; \ |
148 | 147 | |
149 | 148 | |
150 | 149 | |
151 | 150 | |
152 | 151 | |
153 | 152 | |
... | ... | @@ -164,33 +163,34 @@ |
164 | 163 | "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \ |
165 | 164 | "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \ |
166 | 165 | "rdpr %%wstate, %%o5\n\t" \ |
167 | - "stx %%o6, [%%g6 + %3]\n\t" \ | |
168 | - "stb %%o5, [%%g6 + %2]\n\t" \ | |
169 | - "rdpr %%cwp, %%o5\n\t" \ | |
166 | + "stx %%o6, [%%g6 + %6]\n\t" \ | |
170 | 167 | "stb %%o5, [%%g6 + %5]\n\t" \ |
171 | - "mov %1, %%g6\n\t" \ | |
172 | - "ldub [%1 + %5], %%g1\n\t" \ | |
168 | + "rdpr %%cwp, %%o5\n\t" \ | |
169 | + "stb %%o5, [%%g6 + %8]\n\t" \ | |
170 | + "mov %4, %%g6\n\t" \ | |
171 | + "ldub [%4 + %8], %%g1\n\t" \ | |
173 | 172 | "wrpr %%g1, %%cwp\n\t" \ |
174 | - "ldx [%%g6 + %3], %%o6\n\t" \ | |
175 | - "ldub [%%g6 + %2], %%o5\n\t" \ | |
176 | - "ldub [%%g6 + %4], %%o7\n\t" \ | |
173 | + "ldx [%%g6 + %6], %%o6\n\t" \ | |
174 | + "ldub [%%g6 + %5], %%o5\n\t" \ | |
175 | + "ldub [%%g6 + %7], %%o7\n\t" \ | |
177 | 176 | "wrpr %%o5, 0x0, %%wstate\n\t" \ |
178 | 177 | "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ |
179 | 178 | "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ |
180 | - "ldx [%%g6 + %6], %%g4\n\t" \ | |
179 | + "ldx [%%g6 + %9], %%g4\n\t" \ | |
181 | 180 | "brz,pt %%o7, 1f\n\t" \ |
182 | 181 | " mov %%g7, %0\n\t" \ |
183 | 182 | "b,a ret_from_syscall\n\t" \ |
184 | 183 | "1:\n\t" \ |
185 | - : "=&r" (last) \ | |
184 | + : "=&r" (last), "=r" (current), "=r" (current_thread_info_reg), \ | |
185 | + "=r" (__local_per_cpu_offset) \ | |
186 | 186 | : "0" (task_thread_info(next)), \ |
187 | 187 | "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD), \ |
188 | 188 | "i" (TI_CWP), "i" (TI_TASK) \ |
189 | 189 | : "cc", \ |
190 | 190 | "g1", "g2", "g3", "g7", \ |
191 | - "l2", "l3", "l4", "l5", "l6", "l7", \ | |
191 | + "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ | |
192 | 192 | "i0", "i1", "i2", "i3", "i4", "i5", \ |
193 | - "o0", "o1", "o2", "o3", "o4", "o5", "o7" EXTRA_CLOBBER);\ | |
193 | + "o0", "o1", "o2", "o3", "o4", "o5", "o7"); \ | |
194 | 194 | /* If you fuck with this, update ret_from_syscall code too. */ \ |
195 | 195 | if (test_thread_flag(TIF_PERFCTR)) { \ |
196 | 196 | write_pcr(current_thread_info()->pcr_reg); \ |