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 |
