Commit c195e079 authored by James Hogan's avatar James Hogan Committed by Ralf Baechle

MIPS: traps: Convert ebase to KSEG0

When allocating boot memory for the exception vector when vectored
interrupts (vint) or vectored external interrupt controllers (veic) are
enabled, try to ensure that the virtual address resides in KSeg0 (and
WARN should that not be possible).

This will be helpful on MIPS64 cores supporting the CP0_EBase Write Gate
(WG) bit once we start using the WG bit to write the full ebase into
CP0_EBase, as we ideally need to avoid hitting the architecturally
poorly defined exception base for Cache Errors when CP0_EBase is in
XKPhys.

An exception is made for Enhanced Virtual Addressing (EVA) kernels which
allow segments to be rearranged and to become uncached during cache
error handling, making it valid for ebase to be elsewhere.
Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
Cc: Matt Redfearn <matt.redfearn@imgtec.com>
Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14149/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 18022894
...@@ -2210,8 +2210,25 @@ void __init trap_init(void) ...@@ -2210,8 +2210,25 @@ void __init trap_init(void)
if (cpu_has_veic || cpu_has_vint) { if (cpu_has_veic || cpu_has_vint) {
unsigned long size = 0x200 + VECTORSPACING*64; unsigned long size = 0x200 + VECTORSPACING*64;
phys_addr_t ebase_pa;
ebase = (unsigned long) ebase = (unsigned long)
__alloc_bootmem(size, 1 << fls(size), 0); __alloc_bootmem(size, 1 << fls(size), 0);
/*
* Try to ensure ebase resides in KSeg0 if possible.
*
* It shouldn't generally be in XKPhys on MIPS64 to avoid
* hitting a poorly defined exception base for Cache Errors.
* The allocation is likely to be in the low 512MB of physical,
* in which case we should be able to convert to KSeg0.
*
* EVA is special though as it allows segments to be rearranged
* and to become uncached during cache error handling.
*/
ebase_pa = __pa(ebase);
if (!IS_ENABLED(CONFIG_EVA) && !WARN_ON(ebase_pa >= 0x20000000))
ebase = CKSEG0ADDR(ebase_pa);
} else { } else {
ebase = CAC_BASE; ebase = CAC_BASE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment