diff options
Diffstat (limited to 'arch/mips/include/asm/stackframe.h')
-rw-r--r-- | arch/mips/include/asm/stackframe.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 28d6d9364bd1..a71da576883c 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h | |||
@@ -152,6 +152,31 @@ | |||
152 | .set noreorder | 152 | .set noreorder |
153 | bltz k0, 8f | 153 | bltz k0, 8f |
154 | move k1, sp | 154 | move k1, sp |
155 | #ifdef CONFIG_EVA | ||
156 | /* | ||
157 | * Flush interAptiv's Return Prediction Stack (RPS) by writing | ||
158 | * EntryHi. Toggling Config7.RPS is slower and less portable. | ||
159 | * | ||
160 | * The RPS isn't automatically flushed when exceptions are | ||
161 | * taken, which can result in kernel mode speculative accesses | ||
162 | * to user addresses if the RPS mispredicts. That's harmless | ||
163 | * when user and kernel share the same address space, but with | ||
164 | * EVA the same user segments may be unmapped to kernel mode, | ||
165 | * even containing sensitive MMIO regions or invalid memory. | ||
166 | * | ||
167 | * This can happen when the kernel sets the return address to | ||
168 | * ret_from_* and jr's to the exception handler, which looks | ||
169 | * more like a tail call than a function call. If nested calls | ||
170 | * don't evict the last user address in the RPS, it will | ||
171 | * mispredict the return and fetch from a user controlled | ||
172 | * address into the icache. | ||
173 | * | ||
174 | * More recent EVA-capable cores with MAAR to restrict | ||
175 | * speculative accesses aren't affected. | ||
176 | */ | ||
177 | MFC0 k0, CP0_ENTRYHI | ||
178 | MTC0 k0, CP0_ENTRYHI | ||
179 | #endif | ||
155 | .set reorder | 180 | .set reorder |
156 | /* Called from user mode, new stack. */ | 181 | /* Called from user mode, new stack. */ |
157 | get_saved_sp | 182 | get_saved_sp |