Hi Mike. On Thu, Apr 11, 2024 at 07:00:42PM +0300, Mike Rapoport wrote: > From: "Mike Rapoport (IBM)" <rppt@xxxxxxxxxx> > > Several architectures override module_alloc() only to define address > range for code allocations different than VMALLOC address space. > > Provide a generic implementation in execmem that uses the parameters for > address space ranges, required alignment and page protections provided > by architectures. > > The architectures must fill execmem_info structure and implement > execmem_arch_setup() that returns a pointer to that structure. This way the > execmem initialization won't be called from every architecture, but rather > from a central place, namely a core_initcall() in execmem. > > The execmem provides execmem_alloc() API that wraps __vmalloc_node_range() > with the parameters defined by the architectures. If an architecture does > not implement execmem_arch_setup(), execmem_alloc() will fall back to > module_alloc(). > > Signed-off-by: Mike Rapoport (IBM) <rppt@xxxxxxxxxx> > --- This code snippet could be more readable ... > diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c > index 66c45a2764bc..b70047f944cc 100644 > --- a/arch/sparc/kernel/module.c > +++ b/arch/sparc/kernel/module.c > @@ -14,6 +14,7 @@ > #include <linux/string.h> > #include <linux/ctype.h> > #include <linux/mm.h> > +#include <linux/execmem.h> > > #include <asm/processor.h> > #include <asm/spitfire.h> > @@ -21,34 +22,26 @@ > > #include "entry.h" > > +static struct execmem_info execmem_info __ro_after_init = { > + .ranges = { > + [EXECMEM_DEFAULT] = { > #ifdef CONFIG_SPARC64 > - > -#include <linux/jump_label.h> > - > -static void *module_map(unsigned long size) > -{ > - if (PAGE_ALIGN(size) > MODULES_LEN) > - return NULL; > - return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, > - GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, > - __builtin_return_address(0)); > -} > + .start = MODULES_VADDR, > + .end = MODULES_END, > #else > -static void *module_map(unsigned long size) > + .start = VMALLOC_START, > + .end = VMALLOC_END, > +#endif > + .alignment = 1, > + }, > + }, > +}; > + > +struct execmem_info __init *execmem_arch_setup(void) > { > - return vmalloc(size); > -} > -#endif /* CONFIG_SPARC64 */ > - > -void *module_alloc(unsigned long size) > -{ > - void *ret; > - > - ret = module_map(size); > - if (ret) > - memset(ret, 0, size); > + execmem_info.ranges[EXECMEM_DEFAULT].pgprot = PAGE_KERNEL; > > - return ret; > + return &execmem_info; > } > > /* Make generic code ignore STT_REGISTER dummy undefined symbols. */ ... if the following was added: diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index 9e85d57ac3f2..62bcafe38b1f 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h @@ -432,6 +432,8 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, #define VMALLOC_START _AC(0xfe600000,UL) #define VMALLOC_END _AC(0xffc00000,UL) +#define MODULES_VADDR VMALLOC_START +#define MODULES_END VMALLOC_END Then the #ifdef CONFIG_SPARC64 could be dropped and the code would be the same for 32 and 64 bits. Just a drive-by comment. Sam