diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2021-08-20 20:34:31 +1000 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2021-08-20 22:35:18 +1000 |
commit | 787c70f2f9990b5a197320152d2fc32cd8a6ad1a (patch) | |
tree | a8103d3b32d9f20c026530ccf0f2a4eedfa73722 /arch | |
parent | 310d2e83cb9b7f1e7232319880e3fcb57592fa10 (diff) |
powerpc/64s: Fix scv implicit soft-mask table for relocated kernels
The implict soft-mask table addresses get relocated if they use a
relative symbol like a label. This is right for code that runs relocated
but not for unrelocated. The scv interrupt vectors run unrelocated, so
absolute addresses are required for their soft-mask table entry.
This fixes crashing with relocated kernels, usually an asynchronous
interrupt hitting in the scv handler, then hitting the trap that checks
whether r1 is in userspace.
Fixes: 325678fd0522 ("powerpc/64s: add a table of implicit soft-masked addresses")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210820103431.1701240-1-npiggin@gmail.com
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 4aec59a77d4c..37859e62a8dc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -812,7 +812,6 @@ __start_interrupts: * syscall register convention is in Documentation/powerpc/syscall64-abi.rst */ EXC_VIRT_BEGIN(system_call_vectored, 0x3000, 0x1000) -1: /* SCV 0 */ mr r9,r13 GET_PACA(r13) @@ -842,10 +841,12 @@ EXC_VIRT_BEGIN(system_call_vectored, 0x3000, 0x1000) b system_call_vectored_sigill #endif .endr -2: EXC_VIRT_END(system_call_vectored, 0x3000, 0x1000) -SOFT_MASK_TABLE(1b, 2b) // Treat scv vectors as soft-masked, see comment above. +// Treat scv vectors as soft-masked, see comment above. +// Use absolute values rather than labels here, so they don't get relocated, +// because this code runs unrelocated. +SOFT_MASK_TABLE(0xc000000000003000, 0xc000000000004000) #ifdef CONFIG_RELOCATABLE TRAMP_VIRT_BEGIN(system_call_vectored_tramp) |