diff options
author | Christophe Leroy <christophe.leroy@csgroup.eu> | 2021-03-10 17:46:45 +0000 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2021-04-03 21:21:49 +1100 |
commit | 111631b5e9dae764754657aad00bd6cd1a805d0d (patch) | |
tree | 44c407b07738ac27c790e51da133624b2ba2db3e /arch/powerpc/kernel/align.c | |
parent | 35506a3e2d7c4d93cb564e23471a448cbd98f085 (diff) |
powerpc/align: Don't use __get_user_instr() on kernel addresses
In the old days, when we didn't have kernel userspace access
protection and had set_fs(), it was wise to use __get_user()
and friends to read kernel memory.
Nowadays, get_user() is granting userspace access and is exclusively
for userspace access.
In alignment exception handler, use probe_kernel_read_inst()
instead of __get_user_instr() for reading instructions in kernel.
This will allow to remove the is_kernel_addr() check in
__get/put_user() in a following patch.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/d9ecbce00178484e66ca7adec2ff210058037704.1615398265.git.christophe.leroy@csgroup.eu
Diffstat (limited to 'arch/powerpc/kernel/align.c')
-rw-r--r-- | arch/powerpc/kernel/align.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index f362c99213be..a97d5f1a3905 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -310,7 +310,12 @@ int fix_alignment(struct pt_regs *regs) */ CHECK_FULL_REGS(regs); - if (unlikely(__get_user_instr(instr, (void __user *)regs->nip))) + if (is_kernel_addr(regs->nip)) + r = probe_kernel_read_inst(&instr, (void *)regs->nip); + else + r = __get_user_instr(instr, (void __user *)regs->nip); + + if (unlikely(r)) return -EFAULT; if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { /* We don't handle PPC little-endian any more... */ |