On book3s32 (hash), exec protection is set per 256Mb segments with NX bit.
Instead of clearing NX bit on vmalloc space when CONFIG_MODULES is selected,
allocate modules in a dedicated segment (0xb0000000-0xbfffffff by default).
This allows to keep exec protection on vmalloc space while allowing exec
on modules.
Christophe Leroy (8):
powerpc/ptdump: Refactor update of st->last_pa
powerpc/ptdump: Refactor update of pg_state
powerpc: Set user/kernel boundary at TASK_SIZE instead of PAGE_OFFSET
powerpc/lib: Prepare code-patching for modules allocated outside
vmalloc space
powerpc: Use MODULES_VADDR if defined
powerpc/32s: Only leave NX unset on segments used for modules
powerpc/32s: Kernel space starts at TASK_SIZE
powerpc/32s: Use dedicated segment for modules with STRICT_KERNEL_RWX
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/book3s/32/pgtable.h | 15 ++----
arch/powerpc/include/asm/page.h | 2 +-
arch/powerpc/kernel/head_32.S | 12 ++---
arch/powerpc/kernel/module.c | 11 ++++
arch/powerpc/lib/code-patching.c | 2 +-
arch/powerpc/mm/book3s32/hash_low.S | 2 +-
arch/powerpc/mm/book3s32/mmu.c | 17 +++++--
arch/powerpc/mm/kasan/kasan_init_32.c | 6 +++
arch/powerpc/mm/ptdump/ptdump.c | 53 ++++++++++++--------
10 files changed, 78 insertions(+), 43 deletions(-)
--
2.25.0
st->last_pa is always updated in note_page() so it can
be done outside the if/elseif/else block.
Signed-off-by: Christophe Leroy <redacted>
---
arch/powerpc/mm/ptdump/ptdump.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
In note_page(), the pg_state is updated the same way in two places.
Add note_page_update_state() to do it.
Also include the display of boundary markers there as it is missing
"no level" leg, leading to a mismatch when the first two markers
are at the same address and the first displayed area uses that
address.
Signed-off-by: Christophe Leroy <redacted>
---
arch/powerpc/mm/ptdump/ptdump.c | 34 +++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
@@ -203,12 +221,8 @@ static void note_page(struct pg_state *st, unsigned long addr,/* At first no level is set */if(!st->level){-st->level=level;-st->current_flags=flag;-st->start_address=addr;-st->start_pa=pa;-st->page_size=page_size;pt_dump_seq_printf(st->seq,"---[ %s ]---\n",st->marker->name);+note_page_update_state(st,addr,level,val,page_size);/**Dumpthesectionofvirtualmemorywhen:*-thePTEflagsfromoneentrytothenextdiffers.
In order to allow allocation of modules outside of vmalloc space,
use MODULES_VADDR and MODULES_END when MODULES_VADDR is defined.
Redefine module_alloc() when MODULES_VADDR defined.
Unmap corresponding KASAN shadow memory.
Signed-off-by: Christophe Leroy <redacted>
---
arch/powerpc/kernel/module.c | 11 +++++++++++
arch/powerpc/mm/kasan/kasan_init_32.c | 6 ++++++
2 files changed, 17 insertions(+)
When STRICT_KERNEL_RWX is set, we want to set NX bit on vmalloc
segments. But modules require exec.
Use a dedicated segment for modules. There is not much space
above kernel, and we don't waste vmalloc space to do alignment.
Therefore, we take the segment before PAGE_OFFSET for modules.
Signed-off-by: Christophe Leroy <redacted>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/book3s/32/pgtable.h | 15 +++++----------
arch/powerpc/mm/ptdump/ptdump.c | 8 ++++++++
3 files changed, 14 insertions(+), 10 deletions(-)
@@ -1198,6 +1198,7 @@ config TASK_SIZE_BOOLconfigTASK_SIZEhex"Size of user task space"ifTASK_SIZE_BOOLdefault"0x80000000"ifPPC_8xx+default"0xb0000000"ifPPC_BOOK3S_32&&STRICT_KERNEL_RWXdefault"0xc0000000"endmenu
Instead of leaving NX unset on all segments above the start
of vmalloc space, only leave NX unset on segments used for
modules.
Signed-off-by: Christophe Leroy <redacted>
---
arch/powerpc/mm/book3s32/mmu.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
@@ -187,6 +187,17 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)return__mmu_mapin_ram(border,top);}+staticboolis_module_segment(unsignedlongaddr)+{+if(!IS_ENABLED(CONFIG_MODULES))+returnfalse;+if(addr<ALIGN_DOWN(VMALLOC_START,SZ_256M))+returnfalse;+if(addr>=ALIGN(VMALLOC_END,SZ_256M))+returnfalse;+returntrue;+}+voidmmu_mark_initmem_nx(void){intnb=mmu_has_feature(MMU_FTR_USE_HIGH_BATS)?8:4;
@@ -223,9 +234,9 @@ void mmu_mark_initmem_nx(void)for(i=TASK_SIZE>>28;i<16;i++){/* Do not set NX on VM space for modules */-if(IS_ENABLED(CONFIG_MODULES)&&-(VMALLOC_START&0xf0000000)==i<<28)-break;+if(is_module_segment(i<<28))+continue;+mtsrin(mfsrin(i<<28)|0x10000000,i<<28);}}
User space stops at TASK_SIZE. At the moment, kernel space starts
at PAGE_OFFSET.
In order to use space between TASK_SIZE and PAGE_OFFSET for modules,
make TASK_SIZE the limit between user and kernel space.
Note that fault.c already considers TASK_SIZE as the boundary between
user and kernel space.
Signed-off-by: Christophe Leroy <redacted>
---
arch/powerpc/include/asm/page.h | 2 +-
arch/powerpc/mm/ptdump/ptdump.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
From: kernel test robot <hidden> Date: 2020-06-20 11:30:36
Hi Christophe,
I love your patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.8-rc1 next-20200618]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc-32s-Allocate-modules-outside-of-vmalloc-space-for-STRICT_KERNEL_RWX/20200620-001346
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc64-randconfig-r023-20200619 (attached as .config)
compiler: powerpc64le-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>
All error/warnings (new ones prefixed by >>):
In file included from arch/powerpc/include/asm/book3s/64/mmu-hash.h:22,
from arch/powerpc/include/asm/book3s/64/mmu.h:46,
from arch/powerpc/include/asm/mmu.h:348,
from arch/powerpc/include/asm/lppaca.h:47,
from arch/powerpc/include/asm/paca.h:17,
from arch/powerpc/include/asm/current.h:13,
from include/linux/thread_info.h:21,
from include/asm-generic/preempt.h:5,
from ./arch/powerpc/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:51,
from include/linux/seqlock.h:36,
from include/linux/time.h:6,
from include/linux/compat.h:10,
from arch/powerpc/kernel/asm-offsets.c:14:
arch/powerpc/include/asm/book3s/64/mmu-hash.h: In function 'get_kernel_vsid':
quoted
arch/powerpc/include/asm/task_size_64.h:48:3: error: implicit declaration of function 'test_tsk_thread_flag' [-Werror=implicit-function-declaration]
arch/powerpc/include/asm/book3s/64/mmu-hash.h:836:7: note: in expansion of macro 'is_kernel_addr'
836 | if (!is_kernel_addr(ea))
| ^~~~~~~~~~~~~~
arch/powerpc/include/asm/task_size_64.h:51:32: note: each undeclared identifier is reported only once for each function it appears in
51 | #define TASK_SIZE TASK_SIZE_OF(current)
| ^~~~~~~
arch/powerpc/include/asm/task_size_64.h:48:24: note: in definition of macro 'TASK_SIZE_OF'
48 | (test_tsk_thread_flag(tsk, TIF_32BIT) ? TASK_SIZE_USER32 : \
| ^~~
quoted
arch/powerpc/include/asm/page.h:259:35: note: in expansion of macro 'TASK_SIZE'
arch/powerpc/include/asm/book3s/64/mmu-hash.h:836:7: note: in expansion of macro 'is_kernel_addr'
836 | if (!is_kernel_addr(ea))
| ^~~~~~~~~~~~~~
In file included from include/linux/uaccess.h:5,
from include/linux/crypto.h:21,
from include/crypto/hash.h:11,
from include/linux/uio.h:10,
from include/linux/socket.h:8,
from include/linux/compat.h:15,
from arch/powerpc/kernel/asm-offsets.c:14:
include/linux/sched.h: At top level:
quoted
include/linux/sched.h:1786:19: error: static declaration of 'test_tsk_thread_flag' follows non-static declaration
1786 | static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag)
| ^~~~~~~~~~~~~~~~~~~~
In file included from arch/powerpc/include/asm/book3s/64/mmu-hash.h:22,
from arch/powerpc/include/asm/book3s/64/mmu.h:46,
from arch/powerpc/include/asm/mmu.h:348,
from arch/powerpc/include/asm/lppaca.h:47,
from arch/powerpc/include/asm/paca.h:17,
from arch/powerpc/include/asm/current.h:13,
from include/linux/thread_info.h:21,
from include/asm-generic/preempt.h:5,
from ./arch/powerpc/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:51,
from include/linux/seqlock.h:36,
from include/linux/time.h:6,
from include/linux/compat.h:10,
from arch/powerpc/kernel/asm-offsets.c:14:
arch/powerpc/include/asm/task_size_64.h:48:3: note: previous implicit declaration of 'test_tsk_thread_flag' was here
48 | (test_tsk_thread_flag(tsk, TIF_32BIT) ? TASK_SIZE_USER32 : \
| ^~~~~~~~~~~~~~~~~~~~
quoted
arch/powerpc/include/asm/task_size_64.h:51:19: note: in expansion of macro 'TASK_SIZE_OF'
arch/powerpc/include/asm/book3s/64/mmu-hash.h:836:7: note: in expansion of macro 'is_kernel_addr'
836 | if (!is_kernel_addr(ea))
| ^~~~~~~~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:114: arch/powerpc/kernel/asm-offsets.s] Error 1
make[2]: Target '__build' not remade because of errors.
make[1]: *** [Makefile:1188: prepare0] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:185: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.
vim +/TASK_SIZE +259 arch/powerpc/include/asm/page.h
251
252 /*
253 * Don't compare things with KERNELBASE or PAGE_OFFSET to test for
254 * "kernelness", use is_kernel_addr() - it should do what you want.
255 */
256 #ifdef CONFIG_PPC_BOOK3E_64
257 #define is_kernel_addr(x) ((x) >= 0x8000000000000000ul)
258 #else
> 259 #define is_kernel_addr(x) ((x) >= TASK_SIZE)
260 #endif
261
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
From: kernel test robot <hidden> Date: 2020-06-20 12:01:37
Hi Christophe,
I love your patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.8-rc1 next-20200618]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc-32s-Allocate-modules-outside-of-vmalloc-space-for-STRICT_KERNEL_RWX/20200620-001346
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-randconfig-r006-20200619 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 63700971ac9cdf198faa4a3a7c226fa579e49206)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc cross compiling tool for clang build
# apt-get install binutils-powerpc-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>
All errors (new ones prefixed by >>):
In file included from arch/powerpc/kernel/asm-offsets.c:14:
In file included from include/linux/compat.h:10:
In file included from include/linux/time.h:6:
In file included from include/linux/seqlock.h:36:
In file included from include/linux/spinlock.h:51:
In file included from include/linux/preempt.h:78:
In file included from ./arch/powerpc/include/generated/asm/preempt.h:1:
In file included from include/asm-generic/preempt.h:5:
In file included from include/linux/thread_info.h:21:
In file included from arch/powerpc/include/asm/current.h:13:
In file included from arch/powerpc/include/asm/paca.h:17:
In file included from arch/powerpc/include/asm/lppaca.h:47:
In file included from arch/powerpc/include/asm/mmu.h:348:
In file included from arch/powerpc/include/asm/book3s/64/mmu.h:46:
quoted
arch/powerpc/include/asm/book3s/64/mmu-hash.h:836:7: error: implicit declaration of function 'test_tsk_thread_flag' [-Werror,-Wimplicit-function-declaration]
if (!is_kernel_addr(ea))
^
arch/powerpc/include/asm/page.h:259:35: note: expanded from macro 'is_kernel_addr'
#define is_kernel_addr(x) ((x) >= TASK_SIZE)
^
arch/powerpc/include/asm/task_size_64.h:51:19: note: expanded from macro 'TASK_SIZE'
#define TASK_SIZE TASK_SIZE_OF(current)
^
arch/powerpc/include/asm/task_size_64.h:48:3: note: expanded from macro 'TASK_SIZE_OF'
(test_tsk_thread_flag(tsk, TIF_32BIT) ? TASK_SIZE_USER32 : \
^
In file included from arch/powerpc/kernel/asm-offsets.c:14:
In file included from include/linux/compat.h:10:
In file included from include/linux/time.h:6:
In file included from include/linux/seqlock.h:36:
In file included from include/linux/spinlock.h:51:
In file included from include/linux/preempt.h:78:
In file included from ./arch/powerpc/include/generated/asm/preempt.h:1:
In file included from include/asm-generic/preempt.h:5:
In file included from include/linux/thread_info.h:21:
In file included from arch/powerpc/include/asm/current.h:13:
In file included from arch/powerpc/include/asm/paca.h:17:
In file included from arch/powerpc/include/asm/lppaca.h:47:
In file included from arch/powerpc/include/asm/mmu.h:348:
In file included from arch/powerpc/include/asm/book3s/64/mmu.h:46:
quoted
arch/powerpc/include/asm/book3s/64/mmu-hash.h:836:7: error: use of undeclared identifier 'current'
arch/powerpc/include/asm/page.h:259:35: note: expanded from macro 'is_kernel_addr'
#define is_kernel_addr(x) ((x) >= TASK_SIZE)
^
arch/powerpc/include/asm/task_size_64.h:51:32: note: expanded from macro 'TASK_SIZE'
#define TASK_SIZE TASK_SIZE_OF(current)
^
In file included from arch/powerpc/kernel/asm-offsets.c:14:
In file included from include/linux/compat.h:10:
In file included from include/linux/time.h:6:
In file included from include/linux/seqlock.h:36:
In file included from include/linux/spinlock.h:51:
In file included from include/linux/preempt.h:78:
In file included from ./arch/powerpc/include/generated/asm/preempt.h:1:
In file included from include/asm-generic/preempt.h:5:
In file included from include/linux/thread_info.h:21:
In file included from arch/powerpc/include/asm/current.h:13:
In file included from arch/powerpc/include/asm/paca.h:17:
In file included from arch/powerpc/include/asm/lppaca.h:47:
In file included from arch/powerpc/include/asm/mmu.h:348:
In file included from arch/powerpc/include/asm/book3s/64/mmu.h:46:
quoted
arch/powerpc/include/asm/book3s/64/mmu-hash.h:836:7: error: use of undeclared identifier 'TIF_32BIT'
arch/powerpc/include/asm/page.h:259:35: note: expanded from macro 'is_kernel_addr'
#define is_kernel_addr(x) ((x) >= TASK_SIZE)
^
arch/powerpc/include/asm/task_size_64.h:51:19: note: expanded from macro 'TASK_SIZE'
#define TASK_SIZE TASK_SIZE_OF(current)
^
arch/powerpc/include/asm/task_size_64.h:48:29: note: expanded from macro 'TASK_SIZE_OF'
(test_tsk_thread_flag(tsk, TIF_32BIT) ? TASK_SIZE_USER32 : \
^
In file included from arch/powerpc/kernel/asm-offsets.c:14:
In file included from include/linux/compat.h:15:
In file included from include/linux/socket.h:8:
In file included from include/linux/uio.h:10:
In file included from include/crypto/hash.h:11:
In file included from include/linux/crypto.h:21:
In file included from include/linux/uaccess.h:5:
quoted
include/linux/sched.h:1786:19: error: static declaration of 'test_tsk_thread_flag' follows non-static declaration
static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag)
^
arch/powerpc/include/asm/book3s/64/mmu-hash.h:836:7: note: previous implicit declaration is here
if (!is_kernel_addr(ea))
^
arch/powerpc/include/asm/page.h:259:35: note: expanded from macro 'is_kernel_addr'
#define is_kernel_addr(x) ((x) >= TASK_SIZE)
^
arch/powerpc/include/asm/task_size_64.h:51:19: note: expanded from macro 'TASK_SIZE'
#define TASK_SIZE TASK_SIZE_OF(current)
^
arch/powerpc/include/asm/task_size_64.h:48:3: note: expanded from macro 'TASK_SIZE_OF'
(test_tsk_thread_flag(tsk, TIF_32BIT) ? TASK_SIZE_USER32 : \
^
In file included from arch/powerpc/kernel/asm-offsets.c:21:
include/linux/mman.h:133:9: warning: division by zero is undefined [-Wdivision-by-zero]
_calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ) |
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/mman.h:111:21: note: expanded from macro '_calc_vm_trans'
: ((x) & (bit1)) / ((bit1) / (bit2))))
^ ~~~~~~~~~~~~~~~~~
include/linux/mman.h:134:9: warning: division by zero is undefined [-Wdivision-by-zero]
_calc_vm_trans(flags, MAP_SYNC, VM_SYNC );
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/mman.h:111:21: note: expanded from macro '_calc_vm_trans'
: ((x) & (bit1)) / ((bit1) / (bit2))))
^ ~~~~~~~~~~~~~~~~~
2 warnings and 4 errors generated.
make[2]: *** [scripts/Makefile.build:114: arch/powerpc/kernel/asm-offsets.s] Error 1
make[2]: Target '__build' not remade because of errors.
make[1]: *** [Makefile:1188: prepare0] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:185: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.
vim +/test_tsk_thread_flag +836 arch/powerpc/include/asm/book3s/64/mmu-hash.h
4ffe713b7587b1 arch/powerpc/include/asm/book3s/64/mmu-hash.h Aneesh Kumar K.V 2018-09-20 828
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 829 /*
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 830 * This is only valid for addresses >= PAGE_OFFSET
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 831 */
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 832 static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 833 {
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 834 unsigned long context;
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 835
85beb1c486df76 arch/powerpc/include/asm/book3s/64/mmu-hash.h Michael Ellerman 2017-03-29 @836 if (!is_kernel_addr(ea))
85beb1c486df76 arch/powerpc/include/asm/book3s/64/mmu-hash.h Michael Ellerman 2017-03-29 837 return 0;
85beb1c486df76 arch/powerpc/include/asm/book3s/64/mmu-hash.h Michael Ellerman 2017-03-29 838
4ffe713b7587b1 arch/powerpc/include/asm/book3s/64/mmu-hash.h Aneesh Kumar K.V 2018-09-20 839 context = get_kernel_context(ea);
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 840 return get_vsid(context, ea, ssize);
c60ac5693c47df arch/powerpc/include/asm/mmu-hash64.h Aneesh Kumar K.V 2013-03-13 841 }
5c3c7ede2bdcb8 arch/powerpc/include/asm/mmu-hash64.h David Gibson 2016-02-09 842
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org