Message ID | 20221209131052.64235-1-xander.moerkerken@omron.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Added ability to vmalloc executable memory | expand |
On Fri, Dec 09, 2022 at 02:10:52PM +0100, Xander Moerkerken wrote: > From: Xander Moerkerken <xander.moerkerken@gmail.com> > > Since release 5.8-rc1 the pgprot got removed from __vmalloc > because the only usage was PAGE_KERNEL as argument. > However, this removes the ability to input other arguments > such as 'PAGE_KERNEL_EXEC', which can be used to allocate > memory in which you can execute. For this reason a new > function is introduced called '__vmalloc_exec'. > > Signed-off-by: Xander Moerkerken <xander.moerkerken@omron.com> What is this going to be used for? There's no user from this patch alone, as a module or otherwise. Mark. > --- > include/linux/vmalloc.h | 1 + > mm/vmalloc.c | 8 ++++++++ > 2 files changed, 9 insertions(+) > > diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h > index 096d48aa3437..10c46513b6b2 100644 > --- a/include/linux/vmalloc.h > +++ b/include/linux/vmalloc.h > @@ -147,6 +147,7 @@ extern void *vzalloc_node(unsigned long size, int node) __alloc_size(1); > extern void *vmalloc_32(unsigned long size) __alloc_size(1); > extern void *vmalloc_32_user(unsigned long size) __alloc_size(1); > extern void *__vmalloc(unsigned long size, gfp_t gfp_mask) __alloc_size(1); > +extern void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) __alloc_size(1); > extern void *__vmalloc_node_range(unsigned long size, unsigned long align, > unsigned long start, unsigned long end, gfp_t gfp_mask, > pgprot_t prot, unsigned long vm_flags, int node, > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > index ccaa461998f3..8fd01ed7082b 100644 > --- a/mm/vmalloc.c > +++ b/mm/vmalloc.c > @@ -3294,6 +3294,14 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask) > } > EXPORT_SYMBOL(__vmalloc); > > + > +void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > +{ > + return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, > + NUMA_NO_NODE, __builtin_return_address(0)); > +} > +EXPORT_SYMBOL(__vmalloc_exec); > + > /** > * vmalloc - allocate virtually contiguous memory > * @size: allocation size > -- > 2.37.2 >
The pgprot parameter got removed because, according to the commit log, for no other apparent reason than it being called with 'PAGE_KERNEL' as an argument in the whole kernel. Therefore it got removed. This removed the ability to allocate virtual memory with executing rights. My use case comes from ioremap(). I think this is useful for others too. I don't see why this pgprot parameter got removed but this is the alternative to reverting it to the older 5.7 function. On Fri, 9 Dec 2022 at 14:17, Mark Rutland <mark.rutland@arm.com> wrote: > On Fri, Dec 09, 2022 at 02:10:52PM +0100, Xander Moerkerken wrote: > > From: Xander Moerkerken <xander.moerkerken@gmail.com> > > > > Since release 5.8-rc1 the pgprot got removed from __vmalloc > > because the only usage was PAGE_KERNEL as argument. > > However, this removes the ability to input other arguments > > such as 'PAGE_KERNEL_EXEC', which can be used to allocate > > memory in which you can execute. For this reason a new > > function is introduced called '__vmalloc_exec'. > > > > Signed-off-by: Xander Moerkerken <xander.moerkerken@omron.com> > > What is this going to be used for? There's no user from this patch alone, > as a > module or otherwise. > > Mark. > > > --- > > include/linux/vmalloc.h | 1 + > > mm/vmalloc.c | 8 ++++++++ > > 2 files changed, 9 insertions(+) > > > > diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h > > index 096d48aa3437..10c46513b6b2 100644 > > --- a/include/linux/vmalloc.h > > +++ b/include/linux/vmalloc.h > > @@ -147,6 +147,7 @@ extern void *vzalloc_node(unsigned long size, int > node) __alloc_size(1); > > extern void *vmalloc_32(unsigned long size) __alloc_size(1); > > extern void *vmalloc_32_user(unsigned long size) __alloc_size(1); > > extern void *__vmalloc(unsigned long size, gfp_t gfp_mask) > __alloc_size(1); > > +extern void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > __alloc_size(1); > > extern void *__vmalloc_node_range(unsigned long size, unsigned long > align, > > unsigned long start, unsigned long end, gfp_t > gfp_mask, > > pgprot_t prot, unsigned long vm_flags, int node, > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > > index ccaa461998f3..8fd01ed7082b 100644 > > --- a/mm/vmalloc.c > > +++ b/mm/vmalloc.c > > @@ -3294,6 +3294,14 @@ void *__vmalloc(unsigned long size, gfp_t > gfp_mask) > > } > > EXPORT_SYMBOL(__vmalloc); > > > > + > > +void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > > +{ > > + return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, > > + NUMA_NO_NODE, > __builtin_return_address(0)); > > +} > > +EXPORT_SYMBOL(__vmalloc_exec); > > + > > /** > > * vmalloc - allocate virtually contiguous memory > > * @size: allocation size > > -- > > 2.37.2 > > >
Le 09/12/2022 à 14:38, Xander a écrit : > > The pgprot parameter got removed because, according to the commit log, > for no other apparent reason than it being called with 'PAGE_KERNEL' as > an argument in the whole kernel. Therefore it got removed. > This removed the ability to allocate virtual memory with executing rights. > My use case comes from ioremap(). > I think this is useful for others too. > > I don't see why this pgprot parameter got removed but this is the > alternative to reverting it to the older 5.7 function. Please avoid top-posting, and use only plain text. I think you don't answer to Mark's question. You are adding a new function that no driver uses apparently. If you are working on some piece of code that needs this new fonction, you can send this patch as part of a patch series including that code. By the way, when you need executable memory, the fonction to use is module_alloc(), that's the only function that garanties real executable memory on all platforms. For instance, on some powerpc, setting the X bit is not enough to get executable memory in vmalloc space. Christophe > > On Fri, 9 Dec 2022 at 14:17, Mark Rutland <mark.rutland@arm.com > <mailto:mark.rutland@arm.com>> wrote: > > On Fri, Dec 09, 2022 at 02:10:52PM +0100, Xander Moerkerken wrote: > > From: Xander Moerkerken <xander.moerkerken@gmail.com > <mailto:xander.moerkerken@gmail.com>> > > > > Since release 5.8-rc1 the pgprot got removed from __vmalloc > > because the only usage was PAGE_KERNEL as argument. > > However, this removes the ability to input other arguments > > such as 'PAGE_KERNEL_EXEC', which can be used to allocate > > memory in which you can execute. For this reason a new > > function is introduced called '__vmalloc_exec'. > > > > Signed-off-by: Xander Moerkerken <xander.moerkerken@omron.com > <mailto:xander.moerkerken@omron.com>> > > What is this going to be used for? There's no user from this patch > alone, as a > module or otherwise. > > Mark. > > > --- > > include/linux/vmalloc.h | 1 + > > mm/vmalloc.c | 8 ++++++++ > > 2 files changed, 9 insertions(+) > > > > diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h > > index 096d48aa3437..10c46513b6b2 100644 > > --- a/include/linux/vmalloc.h > > +++ b/include/linux/vmalloc.h > > @@ -147,6 +147,7 @@ extern void *vzalloc_node(unsigned long size, > int node) __alloc_size(1); > > extern void *vmalloc_32(unsigned long size) __alloc_size(1); > > extern void *vmalloc_32_user(unsigned long size) __alloc_size(1); > > extern void *__vmalloc(unsigned long size, gfp_t gfp_mask) > __alloc_size(1); > > +extern void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > __alloc_size(1); > > extern void *__vmalloc_node_range(unsigned long size, unsigned > long align, > > unsigned long start, unsigned long end, > gfp_t gfp_mask, > > pgprot_t prot, unsigned long vm_flags, int > node, > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > > index ccaa461998f3..8fd01ed7082b 100644 > > --- a/mm/vmalloc.c > > +++ b/mm/vmalloc.c > > @@ -3294,6 +3294,14 @@ void *__vmalloc(unsigned long size, gfp_t > gfp_mask) > > } > > EXPORT_SYMBOL(__vmalloc); > > > > + > > +void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > > +{ > > + return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, > > + NUMA_NO_NODE, > __builtin_return_address(0)); > > +} > > +EXPORT_SYMBOL(__vmalloc_exec); > > + > > /** > > * vmalloc - allocate virtually contiguous memory > > * @size: allocation size > > -- > > 2.37.2 > > >
On Fri, 9 Dec 2022 at 14:46, Christophe Leroy <christophe.leroy@csgroup.eu> wrote: > > > > Le 09/12/2022 à 14:38, Xander a écrit : > > > > The pgprot parameter got removed because, according to the commit log, > > for no other apparent reason than it being called with 'PAGE_KERNEL' as > > an argument in the whole kernel. Therefore it got removed. > > This removed the ability to allocate virtual memory with executing rights. > > My use case comes from ioremap(). > > I think this is useful for others too. > > > > I don't see why this pgprot parameter got removed but this is the > > alternative to reverting it to the older 5.7 function. > > Please avoid top-posting, and use only plain text. > > I think you don't answer to Mark's question. > > You are adding a new function that no driver uses apparently. If you are > working on some piece of code that needs this new fonction, you can send > this patch as part of a patch series including that code. > > By the way, when you need executable memory, the fonction to use is > module_alloc(), that's the only function that garanties real executable > memory on all platforms. For instance, on some powerpc, setting the X > bit is not enough to get executable memory in vmalloc space. > > Christophe > Loud and clear, thanks for the feedback. > > > > On Fri, 9 Dec 2022 at 14:17, Mark Rutland <mark.rutland@arm.com > > <mailto:mark.rutland@arm.com>> wrote: > > > > On Fri, Dec 09, 2022 at 02:10:52PM +0100, Xander Moerkerken wrote: > > > From: Xander Moerkerken <xander.moerkerken@gmail.com > > <mailto:xander.moerkerken@gmail.com>> > > > > > > Since release 5.8-rc1 the pgprot got removed from __vmalloc > > > because the only usage was PAGE_KERNEL as argument. > > > However, this removes the ability to input other arguments > > > such as 'PAGE_KERNEL_EXEC', which can be used to allocate > > > memory in which you can execute. For this reason a new > > > function is introduced called '__vmalloc_exec'. > > > > > > Signed-off-by: Xander Moerkerken <xander.moerkerken@omron.com > > <mailto:xander.moerkerken@omron.com>> > > > > What is this going to be used for? There's no user from this patch > > alone, as a > > module or otherwise. > > > > Mark. > > > > > --- > > > include/linux/vmalloc.h | 1 + > > > mm/vmalloc.c | 8 ++++++++ > > > 2 files changed, 9 insertions(+) > > > > > > diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h > > > index 096d48aa3437..10c46513b6b2 100644 > > > --- a/include/linux/vmalloc.h > > > +++ b/include/linux/vmalloc.h > > > @@ -147,6 +147,7 @@ extern void *vzalloc_node(unsigned long size, > > int node) __alloc_size(1); > > > extern void *vmalloc_32(unsigned long size) __alloc_size(1); > > > extern void *vmalloc_32_user(unsigned long size) __alloc_size(1); > > > extern void *__vmalloc(unsigned long size, gfp_t gfp_mask) > > __alloc_size(1); > > > +extern void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > > __alloc_size(1); > > > extern void *__vmalloc_node_range(unsigned long size, unsigned > > long align, > > > unsigned long start, unsigned long end, > > gfp_t gfp_mask, > > > pgprot_t prot, unsigned long vm_flags, int > > node, > > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > > > index ccaa461998f3..8fd01ed7082b 100644 > > > --- a/mm/vmalloc.c > > > +++ b/mm/vmalloc.c > > > @@ -3294,6 +3294,14 @@ void *__vmalloc(unsigned long size, gfp_t > > gfp_mask) > > > } > > > EXPORT_SYMBOL(__vmalloc); > > > > > > + > > > +void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > > > +{ > > > + return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, > > > + NUMA_NO_NODE, > > __builtin_return_address(0)); > > > +} > > > +EXPORT_SYMBOL(__vmalloc_exec); > > > + > > > /** > > > * vmalloc - allocate virtually contiguous memory > > > * @size: allocation size > > > -- > > > 2.37.2 > > > > >
On Fri, Dec 09, 2022 at 01:46:05PM +0000, Christophe Leroy wrote: > > > Le 09/12/2022 à 14:38, Xander a écrit : > > > > The pgprot parameter got removed because, according to the commit log, > > for no other apparent reason than it being called with 'PAGE_KERNEL' as > > an argument in the whole kernel. Therefore it got removed. > > This removed the ability to allocate virtual memory with executing rights. > > My use case comes from ioremap(). > > I think this is useful for others too. > > > > I don't see why this pgprot parameter got removed but this is the > > alternative to reverting it to the older 5.7 function. > > Please avoid top-posting, and use only plain text. > > I think you don't answer to Mark's question. > > You are adding a new function that no driver uses apparently. If you are > working on some piece of code that needs this new fonction, you can send > this patch as part of a patch series including that code. Yup, that was what I was getting at. Thanks for stating that much more clearly than I did. :) > By the way, when you need executable memory, the fonction to use is > module_alloc(), that's the only function that garanties real executable > memory on all platforms. For instance, on some powerpc, setting the X > bit is not enough to get executable memory in vmalloc space. Yup, and likewise on arm64 there are other constraints to consider, e.g. branch ranges, whether or not to set PROT_BTI and/or other prot bits in future. Further, I'm very wary of exporting a generic interface to make some code executable without an understanding and documenting the precise constraints on its use, and I'm generally wary of doing that for some arbitrary code given that could violate other expectations that affect the kernel generally (e.g. gadgets for ROP/JOP/speculation, RELIABLE_STACKTRACE expectations, and general things like whether the code will play with CPU control bits or flags in an unexpected way). Mark. > Christophe > > > > > On Fri, 9 Dec 2022 at 14:17, Mark Rutland <mark.rutland@arm.com > > <mailto:mark.rutland@arm.com>> wrote: > > > > On Fri, Dec 09, 2022 at 02:10:52PM +0100, Xander Moerkerken wrote: > > > From: Xander Moerkerken <xander.moerkerken@gmail.com > > <mailto:xander.moerkerken@gmail.com>> > > > > > > Since release 5.8-rc1 the pgprot got removed from __vmalloc > > > because the only usage was PAGE_KERNEL as argument. > > > However, this removes the ability to input other arguments > > > such as 'PAGE_KERNEL_EXEC', which can be used to allocate > > > memory in which you can execute. For this reason a new > > > function is introduced called '__vmalloc_exec'. > > > > > > Signed-off-by: Xander Moerkerken <xander.moerkerken@omron.com > > <mailto:xander.moerkerken@omron.com>> > > > > What is this going to be used for? There's no user from this patch > > alone, as a > > module or otherwise. > > > > Mark. > > > > > --- > > > include/linux/vmalloc.h | 1 + > > > mm/vmalloc.c | 8 ++++++++ > > > 2 files changed, 9 insertions(+) > > > > > > diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h > > > index 096d48aa3437..10c46513b6b2 100644 > > > --- a/include/linux/vmalloc.h > > > +++ b/include/linux/vmalloc.h > > > @@ -147,6 +147,7 @@ extern void *vzalloc_node(unsigned long size, > > int node) __alloc_size(1); > > > extern void *vmalloc_32(unsigned long size) __alloc_size(1); > > > extern void *vmalloc_32_user(unsigned long size) __alloc_size(1); > > > extern void *__vmalloc(unsigned long size, gfp_t gfp_mask) > > __alloc_size(1); > > > +extern void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > > __alloc_size(1); > > > extern void *__vmalloc_node_range(unsigned long size, unsigned > > long align, > > > unsigned long start, unsigned long end, > > gfp_t gfp_mask, > > > pgprot_t prot, unsigned long vm_flags, int > > node, > > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > > > index ccaa461998f3..8fd01ed7082b 100644 > > > --- a/mm/vmalloc.c > > > +++ b/mm/vmalloc.c > > > @@ -3294,6 +3294,14 @@ void *__vmalloc(unsigned long size, gfp_t > > gfp_mask) > > > } > > > EXPORT_SYMBOL(__vmalloc); > > > > > > + > > > +void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) > > > +{ > > > + return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, > > > + NUMA_NO_NODE, > > __builtin_return_address(0)); > > > +} > > > +EXPORT_SYMBOL(__vmalloc_exec); > > > + > > > /** > > > * vmalloc - allocate virtually contiguous memory > > > * @size: allocation size > > > -- > > > 2.37.2 > > > > >
Hi Xander, Thank you for the patch! Yet something to improve: [auto build test ERROR on akpm-mm/mm-everything] [also build test ERROR on linus/master v6.1-rc8 next-20221208] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Xander-Moerkerken/Added-ability-to-vmalloc-executable-memory/20221209-211212 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20221209131052.64235-1-xander.moerkerken%40omron.com patch subject: [PATCH] Added ability to vmalloc executable memory config: powerpc-allnoconfig compiler: powerpc-linux-gcc (GCC) 12.1.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 # https://github.com/intel-lab-lkp/linux/commit/86c4449bb255bd5320d7b260034db7845878bc12 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Xander-Moerkerken/Added-ability-to-vmalloc-executable-memory/20221209-211212 git checkout 86c4449bb255bd5320d7b260034db7845878bc12 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=powerpc SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): mm/vmalloc.c: In function '__vmalloc_exec': >> mm/vmalloc.c:3314:16: error: implicit declaration of function '__vmalloc_node_prot'; did you mean '__vmalloc_node'? [-Werror=implicit-function-declaration] 3314 | return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, | ^~~~~~~~~~~~~~~~~~~ | __vmalloc_node >> mm/vmalloc.c:3314:16: warning: returning 'int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion] 3314 | return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3315 | NUMA_NO_NODE, __builtin_return_address(0)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +3314 mm/vmalloc.c 3310 3311 3312 void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) 3313 { > 3314 return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, 3315 NUMA_NO_NODE, __builtin_return_address(0)); 3316 } 3317 EXPORT_SYMBOL(__vmalloc_exec); 3318
Hi Xander, Thank you for the patch! Yet something to improve: [auto build test ERROR on akpm-mm/mm-everything] [also build test ERROR on linus/master v6.1-rc8 next-20221208] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Xander-Moerkerken/Added-ability-to-vmalloc-executable-memory/20221209-211212 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20221209131052.64235-1-xander.moerkerken%40omron.com patch subject: [PATCH] Added ability to vmalloc executable memory config: hexagon-randconfig-r041-20221209 compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 6e4cea55f0d1104408b26ac574566a0e4de48036) 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 # https://github.com/intel-lab-lkp/linux/commit/86c4449bb255bd5320d7b260034db7845878bc12 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Xander-Moerkerken/Added-ability-to-vmalloc-executable-memory/20221209-211212 git checkout 86c4449bb255bd5320d7b260034db7845878bc12 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): In file included from mm/vmalloc.c:14: In file included from include/linux/highmem.h:12: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from mm/vmalloc.c:14: In file included from include/linux/highmem.h:12: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from mm/vmalloc.c:14: In file included from include/linux/highmem.h:12: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ >> mm/vmalloc.c:3314:9: error: call to undeclared function '__vmalloc_node_prot'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, ^ >> mm/vmalloc.c:3314:9: error: incompatible integer to pointer conversion returning 'int' from a function with result type 'void *' [-Wint-conversion] return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 warnings and 2 errors generated. vim +/__vmalloc_node_prot +3314 mm/vmalloc.c 3310 3311 3312 void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) 3313 { > 3314 return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, 3315 NUMA_NO_NODE, __builtin_return_address(0)); 3316 } 3317 EXPORT_SYMBOL(__vmalloc_exec); 3318
Hi Xander, Thank you for the patch! Yet something to improve: [auto build test ERROR on akpm-mm/mm-everything] [also build test ERROR on linus/master v6.1-rc8 next-20221208] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Xander-Moerkerken/Added-ability-to-vmalloc-executable-memory/20221209-211212 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20221209131052.64235-1-xander.moerkerken%40omron.com patch subject: [PATCH] Added ability to vmalloc executable memory config: i386-randconfig-a013 compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1) 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 # https://github.com/intel-lab-lkp/linux/commit/86c4449bb255bd5320d7b260034db7845878bc12 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Xander-Moerkerken/Added-ability-to-vmalloc-executable-memory/20221209-211212 git checkout 86c4449bb255bd5320d7b260034db7845878bc12 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): >> mm/vmalloc.c:3314:9: error: implicit declaration of function '__vmalloc_node_prot' is invalid in C99 [-Werror,-Wimplicit-function-declaration] return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, ^ >> mm/vmalloc.c:3314:9: warning: incompatible integer to pointer conversion returning 'int' from a function with result type 'void *' [-Wint-conversion] return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 warning and 1 error generated. vim +/__vmalloc_node_prot +3314 mm/vmalloc.c 3310 3311 3312 void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) 3313 { > 3314 return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, 3315 NUMA_NO_NODE, __builtin_return_address(0)); 3316 } 3317 EXPORT_SYMBOL(__vmalloc_exec); 3318
On Fri, Dec 09, 2022 at 02:10:52PM +0100, Xander Moerkerken wrote: > From: Xander Moerkerken <xander.moerkerken@gmail.com> > > Since release 5.8-rc1 the pgprot got removed from __vmalloc > because the only usage was PAGE_KERNEL as argument. > However, this removes the ability to input other arguments > such as 'PAGE_KERNEL_EXEC', which can be used to allocate > memory in which you can execute. .. which is very much intentional.
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 096d48aa3437..10c46513b6b2 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -147,6 +147,7 @@ extern void *vzalloc_node(unsigned long size, int node) __alloc_size(1); extern void *vmalloc_32(unsigned long size) __alloc_size(1); extern void *vmalloc_32_user(unsigned long size) __alloc_size(1); extern void *__vmalloc(unsigned long size, gfp_t gfp_mask) __alloc_size(1); +extern void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) __alloc_size(1); extern void *__vmalloc_node_range(unsigned long size, unsigned long align, unsigned long start, unsigned long end, gfp_t gfp_mask, pgprot_t prot, unsigned long vm_flags, int node, diff --git a/mm/vmalloc.c b/mm/vmalloc.c index ccaa461998f3..8fd01ed7082b 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3294,6 +3294,14 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask) } EXPORT_SYMBOL(__vmalloc); + +void *__vmalloc_exec(unsigned long size, gfp_t gfp_mask) +{ + return __vmalloc_node_prot(size, 1, gfp_mask, PAGE_KERNEL_EXEC, + NUMA_NO_NODE, __builtin_return_address(0)); +} +EXPORT_SYMBOL(__vmalloc_exec); + /** * vmalloc - allocate virtually contiguous memory * @size: allocation size