powerpc/32s: Implement Kernel Userspace Access Protection
authorChristophe Leroy <christophe.leroy@c-s.fr>
Mon, 11 Mar 2019 08:30:38 +0000 (08:30 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 21 Apr 2019 13:11:47 +0000 (23:11 +1000)
commita68c31fc01ef7863acc0fc74694bf279456a58c4
treedca29a37f12c08381742abc20dc7364aec9fab67
parentf342adca3afc84c4ef648352440ed6331518d72d
powerpc/32s: Implement Kernel Userspace Access Protection

This patch implements Kernel Userspace Access Protection for
book3s/32.

Due to limitations of the processor page protection capabilities,
the protection is only against writing. read protection cannot be
achieved using page protection.

The previous patch modifies the page protection so that RW user
pages are RW for Key 0 and RO for Key 1, and it sets Key 0 for
both user and kernel.

This patch changes userspace segment registers are set to Ku 0
and Ks 1. When kernel needs to write to RW pages, the associated
segment register is then changed to Ks 0 in order to allow write
access to the kernel.

In order to avoid having the read all segment registers when
locking/unlocking the access, some data is kept in the thread_struct
and saved on stack on exceptions. The field identifies both the
first unlocked segment and the first segment following the last
unlocked one. When no segment is unlocked, it contains value 0.

As the hash_page() function is not able to easily determine if a
protfault is due to a bad kernel access to userspace, protfaults
need to be handled by handle_page_fault when KUAP is set.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Drop allow_read/write_to/from_user() as they're now in kup.h,
      and adapt allow_user_access() to do nothing when to == NULL]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/book3s/32/kup.h
arch/powerpc/include/asm/processor.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/head_32.S
arch/powerpc/mm/ppc_mmu_32.c
arch/powerpc/platforms/Kconfig.cputype