Received: by 2002:a05:6500:1b45:b0:1f5:f2ab:c469 with SMTP id cz5csp894809lqb; Wed, 17 Apr 2024 14:06:42 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWgEDRYsMV5HntTFl7/FvDw8CpHNVptT3Ogk7dvyY6I4Y16YjYMHz+HvHnHSgnwjwWV6Yh7qBb3o5ZqXWtxlZn+ZHdkui8kpAlahC1Ssg== X-Google-Smtp-Source: AGHT+IH6VngrSY/sA2lEPi89iYNlGhxNG7O4saTweUJi9+Bz+k/n7CAvbgtWNe81dpoXKa9llW6p X-Received: by 2002:a17:90b:4d81:b0:2a5:32fe:b834 with SMTP id oj1-20020a17090b4d8100b002a532feb834mr661745pjb.23.1713388002003; Wed, 17 Apr 2024 14:06:42 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1713388001; cv=pass; d=google.com; s=arc-20160816; b=bLAmudshVwcaCu/uXufL1ppiO1ECKO6NjVvMN1Ze8WKv1drEThg1qDJyg47UjFA8Y9 fhMtVQqLPyzMXCDrhJbt/bo2cq7MrHH1Gjnru0JYsqh2gcBqt0D6DIueD9z1DSNp7RG6 OXYL5t6Ug6Q7LmbZ/+fjamlBPu7xeqU2FZ8r8eRaxuq4gxcsqMc2PUOg1n7G98yd31pt tYNdV+LIxzT7RvrquMYWl7CpWrAMpt5ibhf8rZe+ZqbayxwPkaAUNeLTObJhEXAcoJrJ n1hMcc+gyUskCFg5j1qvnJtb7pxX0liwIMN94XRef0e2zpQoEbWsUS1Crp096vb511gu /UWw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :subject:cc:to:from:date:dkim-signature; bh=IDy6aDag6vbEIwiMCHoPHWuSkAPoxA+4zWOpSWtkteI=; fh=dfWE8HaEouJtPWs+JJyV0n0nvMaOHK5b2SA+hp6PDLQ=; b=0olhYaWDDVCUNXwvR+S9DzXx0eepVO0ySwIkOTvYppKRxLQ3lkWsGqrdwSHDPO2OSj k9pF527RuB5QHU8BD49CIXqkgijfmSu3h72cyqZpxxMYin5HRcmQtyvLAAUqmIjZFwKw sIWsJh/j1B0d49GHPt3e3dmeW/UARp0v1OpKbHqxVM1gkElxVQLjT70MexlP2t+C1r83 aSJVGd62C4DSYuF/J2p7zd5cYKCEqYsAz6L/ZBvvJJLiZeJVEPR+VksoSyQIKRUeNsy2 JMD80nyXGylfkah7SIlfDXNkdADgKPtAzX/nrb/YZXidoSzuxWdZyHAU8V2Pv3vIk+3R tEGA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=lbBgfz1g; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-149234-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-149234-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id i6-20020a17090ad34600b002ab6324648bsi122976pjx.28.2024.04.17.14.06.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Apr 2024 14:06:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-149234-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=lbBgfz1g; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-149234-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-149234-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 9CDAF28198F for ; Wed, 17 Apr 2024 21:06:41 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EC9CE4D5A2; Wed, 17 Apr 2024 21:06:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lbBgfz1g" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C109481A7; Wed, 17 Apr 2024 21:06:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713387984; cv=none; b=ka2UsoKwoewJsHTQpUAiqdJyhXdxs2Pvqm/jdEgOVni1Dtv590wa7pt8r+GAfBHDR+x8KADJ2Ze0+HJSnYa4Ualb0wSpTi1efes+j/FtIMVk21m0sshr2/Acb00nygCNxr9kDeyvnX62LZzKWTxee0JH2oTGEFd8bLuoj5H/pEc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713387984; c=relaxed/simple; bh=jQajXNUTSdJbOiuE3X14B9u4IThzdGztOYCaLIYkni8=; h=Date:From:To:Cc:Subject:Message-Id:In-Reply-To:References: Mime-Version:Content-Type; b=XKOWuZzeb6nDT7OPOqbMCTw1SjtbX/KmijdfIEhIaW6BUkV9Taz36V5z/g2l3IxitD9v90SVgPHdOMMXIBlLV3btLj0tRVGPwBV9h7t/mccrE3gMNfrrKlS7DcjA7GRIZllE6RkvLkUgKnDrrMqWeSxc42DXa33QphUZAOc4JKM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lbBgfz1g; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 84D73C072AA; Wed, 17 Apr 2024 21:06:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713387983; bh=jQajXNUTSdJbOiuE3X14B9u4IThzdGztOYCaLIYkni8=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=lbBgfz1g+EmTpf/8B5LIXDK5AF+zBI+SdBC4ANMbfR6bQy5kajH30uqxk71pfMuvr cJZB6d+U9AflERemSpVZHriQJFfT/Z8DFuTlYVyXvQJnSapgiRnEO7t/KOgW6pwcaS z5Lm5RAA1OxjUUlwXOrBldmqUzlSWaTXyrLOGADjCWzkJdtuKGaC8DdXWXo4pSdXIV BeW8RFqLQMeqhkQGZ4unhmrg2J0L+4KdO1LN7vnTam7UWqspWie+u+aDSM0c42Q0D+ m9IG0KDe7SBu0YWrOMaaNeWVon+uqrzpeW1LEIVNSnooBS9s9ht4q6rRfMNeSk6pb+ e1WagiG+9QRUg== Date: Thu, 18 Apr 2024 06:06:13 +0900 From: Masami Hiramatsu (Google) To: Mike Rapoport Cc: linux-kernel@vger.kernel.org, Alexandre Ghiti , Andrew Morton , =?UTF-8?B?QmrDtnJuIFTDtnBlbA==?= , Catalin Marinas , Christophe Leroy , "David S. Miller" , Dinh Nguyen , Donald Dutile , Eric Chanudet , Heiko Carstens , Helge Deller , Huacai Chen , Kent Overstreet , Luis Chamberlain , Mark Rutland , Michael Ellerman , Nadav Amit , Palmer Dabbelt , Puranjay Mohan , Rick Edgecombe , Russell King , Song Liu , Steven Rostedt , Thomas Bogendoerfer , Thomas Gleixner , Will Deacon , bpf@vger.kernel.org, linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mips@vger.kernel.org, linux-mm@kvack.org, linux-modules@vger.kernel.org, linux-parisc@vger.kernel.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, loongarch@lists.linux.dev, netdev@vger.kernel.org, sparclinux@vger.kernel.org, x86@kernel.org Subject: Re: [PATCH v4 05/15] mm: introduce execmem_alloc() and execmem_free() Message-Id: <20240418060613.cdcf85650e5d0c43da5d1c1b@kernel.org> In-Reply-To: <20240411160051.2093261-6-rppt@kernel.org> References: <20240411160051.2093261-1-rppt@kernel.org> <20240411160051.2093261-6-rppt@kernel.org> X-Mailer: Sylpheed 3.7.0 (GTK+ 2.24.33; x86_64-pc-linux-gnu) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Thu, 11 Apr 2024 19:00:41 +0300 Mike Rapoport wrote: > From: "Mike Rapoport (IBM)" > > module_alloc() is used everywhere as a mean to allocate memory for code. > > Beside being semantically wrong, this unnecessarily ties all subsystems > that need to allocate code, such as ftrace, kprobes and BPF to modules and > puts the burden of code allocation to the modules code. > > Several architectures override module_alloc() because of various > constraints where the executable memory can be located and this causes > additional obstacles for improvements of code allocation. > > Start splitting code allocation from modules by introducing execmem_alloc() > and execmem_free() APIs. > > Initially, execmem_alloc() is a wrapper for module_alloc() and > execmem_free() is a replacement of module_memfree() to allow updating all > call sites to use the new APIs. > > Since architectures define different restrictions on placement, > permissions, alignment and other parameters for memory that can be used by > different subsystems that allocate executable memory, execmem_alloc() takes > a type argument, that will be used to identify the calling subsystem and to > allow architectures define parameters for ranges suitable for that > subsystem. > This looks good to me for the kprobe part. Acked-by: Masami Hiramatsu (Google) Thank you, > Signed-off-by: Mike Rapoport (IBM) > --- > arch/powerpc/kernel/kprobes.c | 6 ++-- > arch/s390/kernel/ftrace.c | 4 +-- > arch/s390/kernel/kprobes.c | 4 +-- > arch/s390/kernel/module.c | 5 +-- > arch/sparc/net/bpf_jit_comp_32.c | 8 ++--- > arch/x86/kernel/ftrace.c | 6 ++-- > arch/x86/kernel/kprobes/core.c | 4 +-- > include/linux/execmem.h | 57 ++++++++++++++++++++++++++++++++ > include/linux/moduleloader.h | 3 -- > kernel/bpf/core.c | 6 ++-- > kernel/kprobes.c | 8 ++--- > kernel/module/Kconfig | 1 + > kernel/module/main.c | 25 +++++--------- > mm/Kconfig | 3 ++ > mm/Makefile | 1 + > mm/execmem.c | 26 +++++++++++++++ > 16 files changed, 122 insertions(+), 45 deletions(-) > create mode 100644 include/linux/execmem.h > create mode 100644 mm/execmem.c > > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c > index bbca90a5e2ec..9fcd01bb2ce6 100644 > --- a/arch/powerpc/kernel/kprobes.c > +++ b/arch/powerpc/kernel/kprobes.c > @@ -19,8 +19,8 @@ > #include > #include > #include > -#include > #include > +#include > #include > #include > #include > @@ -130,7 +130,7 @@ void *alloc_insn_page(void) > { > void *page; > > - page = module_alloc(PAGE_SIZE); > + page = execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE); > if (!page) > return NULL; > > @@ -142,7 +142,7 @@ void *alloc_insn_page(void) > } > return page; > error: > - module_memfree(page); > + execmem_free(page); > return NULL; > } > > diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c > index c46381ea04ec..798249ef5646 100644 > --- a/arch/s390/kernel/ftrace.c > +++ b/arch/s390/kernel/ftrace.c > @@ -7,13 +7,13 @@ > * Author(s): Martin Schwidefsky > */ > > -#include > #include > #include > #include > #include > #include > #include > +#include > #include > #include > #include > @@ -220,7 +220,7 @@ static int __init ftrace_plt_init(void) > { > const char *start, *end; > > - ftrace_plt = module_alloc(PAGE_SIZE); > + ftrace_plt = execmem_alloc(EXECMEM_FTRACE, PAGE_SIZE); > if (!ftrace_plt) > panic("cannot allocate ftrace plt\n"); > > diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c > index f0cf20d4b3c5..3c1b1be744de 100644 > --- a/arch/s390/kernel/kprobes.c > +++ b/arch/s390/kernel/kprobes.c > @@ -9,7 +9,6 @@ > > #define pr_fmt(fmt) "kprobes: " fmt > > -#include > #include > #include > #include > @@ -21,6 +20,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -38,7 +38,7 @@ void *alloc_insn_page(void) > { > void *page; > > - page = module_alloc(PAGE_SIZE); > + page = execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE); > if (!page) > return NULL; > set_memory_rox((unsigned long)page, 1); > diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c > index 42215f9404af..ac97a905e8cd 100644 > --- a/arch/s390/kernel/module.c > +++ b/arch/s390/kernel/module.c > @@ -21,6 +21,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -76,7 +77,7 @@ void *module_alloc(unsigned long size) > #ifdef CONFIG_FUNCTION_TRACER > void module_arch_cleanup(struct module *mod) > { > - module_memfree(mod->arch.trampolines_start); > + execmem_free(mod->arch.trampolines_start); > } > #endif > > @@ -510,7 +511,7 @@ static int module_alloc_ftrace_hotpatch_trampolines(struct module *me, > > size = FTRACE_HOTPATCH_TRAMPOLINES_SIZE(s->sh_size); > numpages = DIV_ROUND_UP(size, PAGE_SIZE); > - start = module_alloc(numpages * PAGE_SIZE); > + start = execmem_alloc(EXECMEM_FTRACE, numpages * PAGE_SIZE); > if (!start) > return -ENOMEM; > set_memory_rox((unsigned long)start, numpages); > diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c > index da2df1e84ed4..bda2dbd3f4c5 100644 > --- a/arch/sparc/net/bpf_jit_comp_32.c > +++ b/arch/sparc/net/bpf_jit_comp_32.c > @@ -1,10 +1,10 @@ > // SPDX-License-Identifier: GPL-2.0 > -#include > #include > #include > #include > #include > #include > +#include > > #include > #include > @@ -713,7 +713,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; > if (unlikely(proglen + ilen > oldproglen)) { > pr_err("bpb_jit_compile fatal error\n"); > kfree(addrs); > - module_memfree(image); > + execmem_free(image); > return; > } > memcpy(image + proglen, temp, ilen); > @@ -736,7 +736,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; > break; > } > if (proglen == oldproglen) { > - image = module_alloc(proglen); > + image = execmem_alloc(EXECMEM_BPF, proglen); > if (!image) > goto out; > } > @@ -758,7 +758,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; > void bpf_jit_free(struct bpf_prog *fp) > { > if (fp->jited) > - module_memfree(fp->bpf_func); > + execmem_free(fp->bpf_func); > > bpf_prog_unlock_free(fp); > } > diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c > index 70139d9d2e01..c8ddb7abda7c 100644 > --- a/arch/x86/kernel/ftrace.c > +++ b/arch/x86/kernel/ftrace.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include > > @@ -261,15 +262,14 @@ void arch_ftrace_update_code(int command) > #ifdef CONFIG_X86_64 > > #ifdef CONFIG_MODULES > -#include > /* Module allocation simplifies allocating memory for code */ > static inline void *alloc_tramp(unsigned long size) > { > - return module_alloc(size); > + return execmem_alloc(EXECMEM_FTRACE, size); > } > static inline void tramp_free(void *tramp) > { > - module_memfree(tramp); > + execmem_free(tramp); > } > #else > /* Trampolines can only be created if modules are supported */ > diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c > index d0e49bd7c6f3..72e6a45e7ec2 100644 > --- a/arch/x86/kernel/kprobes/core.c > +++ b/arch/x86/kernel/kprobes/core.c > @@ -40,12 +40,12 @@ > #include > #include > #include > -#include > #include > #include > #include > #include > #include > +#include > > #include > #include > @@ -495,7 +495,7 @@ void *alloc_insn_page(void) > { > void *page; > > - page = module_alloc(PAGE_SIZE); > + page = execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE); > if (!page) > return NULL; > > diff --git a/include/linux/execmem.h b/include/linux/execmem.h > new file mode 100644 > index 000000000000..43e7995593a1 > --- /dev/null > +++ b/include/linux/execmem.h > @@ -0,0 +1,57 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef _LINUX_EXECMEM_ALLOC_H > +#define _LINUX_EXECMEM_ALLOC_H > + > +#include > +#include > + > +/** > + * enum execmem_type - types of executable memory ranges > + * > + * There are several subsystems that allocate executable memory. > + * Architectures define different restrictions on placement, > + * permissions, alignment and other parameters for memory that can be used > + * by these subsystems. > + * Types in this enum identify subsystems that allocate executable memory > + * and let architectures define parameters for ranges suitable for > + * allocations by each subsystem. > + * > + * @EXECMEM_DEFAULT: default parameters that would be used for types that > + * are not explcitly defined. > + * @EXECMEM_MODULE_TEXT: parameters for module text sections > + * @EXECMEM_KPROBES: parameters for kprobes > + * @EXECMEM_FTRACE: parameters for ftrace > + * @EXECMEM_BPF: parameters for BPF > + * @EXECMEM_TYPE_MAX: > + */ > +enum execmem_type { > + EXECMEM_DEFAULT, > + EXECMEM_MODULE_TEXT = EXECMEM_DEFAULT, > + EXECMEM_KPROBES, > + EXECMEM_FTRACE, > + EXECMEM_BPF, > + EXECMEM_TYPE_MAX, > +}; > + > +/** > + * execmem_alloc - allocate executable memory > + * @type: type of the allocation > + * @size: how many bytes of memory are required > + * > + * Allocates memory that will contain executable code, either generated or > + * loaded from kernel modules. > + * > + * The memory will have protections defined by architecture for executable > + * region of the @type. > + * > + * Return: a pointer to the allocated memory or %NULL > + */ > +void *execmem_alloc(enum execmem_type type, size_t size); > + > +/** > + * execmem_free - free executable memory > + * @ptr: pointer to the memory that should be freed > + */ > +void execmem_free(void *ptr); > + > +#endif /* _LINUX_EXECMEM_ALLOC_H */ > diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h > index 89b1e0ed9811..a3b8caee9405 100644 > --- a/include/linux/moduleloader.h > +++ b/include/linux/moduleloader.h > @@ -29,9 +29,6 @@ unsigned int arch_mod_section_prepend(struct module *mod, unsigned int section); > sections. Returns NULL on failure. */ > void *module_alloc(unsigned long size); > > -/* Free memory returned from module_alloc. */ > -void module_memfree(void *module_region); > - > /* Determines if the section name is an init section (that is only used during > * module loading). > */ > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c > index 696bc55de8e8..75a54024e2f4 100644 > --- a/kernel/bpf/core.c > +++ b/kernel/bpf/core.c > @@ -22,7 +22,6 @@ > #include > #include > #include > -#include > #include > #include > #include > @@ -37,6 +36,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -1050,12 +1050,12 @@ void bpf_jit_uncharge_modmem(u32 size) > > void *__weak bpf_jit_alloc_exec(unsigned long size) > { > - return module_alloc(size); > + return execmem_alloc(EXECMEM_BPF, size); > } > > void __weak bpf_jit_free_exec(void *addr) > { > - module_memfree(addr); > + execmem_free(addr); > } > > struct bpf_binary_header * > diff --git a/kernel/kprobes.c b/kernel/kprobes.c > index 9d9095e81792..047ca629ce49 100644 > --- a/kernel/kprobes.c > +++ b/kernel/kprobes.c > @@ -26,7 +26,6 @@ > #include > #include > #include > -#include > #include > #include > #include > @@ -39,6 +38,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -113,17 +113,17 @@ enum kprobe_slot_state { > void __weak *alloc_insn_page(void) > { > /* > - * Use module_alloc() so this page is within +/- 2GB of where the > + * Use execmem_alloc() so this page is within +/- 2GB of where the > * kernel image and loaded module images reside. This is required > * for most of the architectures. > * (e.g. x86-64 needs this to handle the %rip-relative fixups.) > */ > - return module_alloc(PAGE_SIZE); > + return execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE); > } > > static void free_insn_page(void *page) > { > - module_memfree(page); > + execmem_free(page); > } > > struct kprobe_insn_cache kprobe_insn_slots = { > diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig > index f3e0329337f6..744383c1eed1 100644 > --- a/kernel/module/Kconfig > +++ b/kernel/module/Kconfig > @@ -2,6 +2,7 @@ > menuconfig MODULES > bool "Enable loadable module support" > modules > + select EXECMEM > help > Kernel modules are small pieces of compiled code which can > be inserted in the running kernel, rather than being > diff --git a/kernel/module/main.c b/kernel/module/main.c > index 5b82b069e0d3..d56b7df0cbb6 100644 > --- a/kernel/module/main.c > +++ b/kernel/module/main.c > @@ -57,6 +57,7 @@ > #include > #include > #include > +#include > #include > #include "internal.h" > > @@ -1179,16 +1180,6 @@ resolve_symbol_wait(struct module *mod, > return ksym; > } > > -void __weak module_memfree(void *module_region) > -{ > - /* > - * This memory may be RO, and freeing RO memory in an interrupt is not > - * supported by vmalloc. > - */ > - WARN_ON(in_interrupt()); > - vfree(module_region); > -} > - > void __weak module_arch_cleanup(struct module *mod) > { > } > @@ -1213,7 +1204,7 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type) > if (mod_mem_use_vmalloc(type)) > ptr = vmalloc(size); > else > - ptr = module_alloc(size); > + ptr = execmem_alloc(EXECMEM_MODULE_TEXT, size); > > if (!ptr) > return -ENOMEM; > @@ -1244,7 +1235,7 @@ static void module_memory_free(struct module *mod, enum mod_mem_type type) > if (mod_mem_use_vmalloc(type)) > vfree(ptr); > else > - module_memfree(ptr); > + execmem_free(ptr); > } > > static void free_mod_mem(struct module *mod) > @@ -2496,9 +2487,9 @@ static void do_free_init(struct work_struct *w) > > llist_for_each_safe(pos, n, list) { > initfree = container_of(pos, struct mod_initfree, node); > - module_memfree(initfree->init_text); > - module_memfree(initfree->init_data); > - module_memfree(initfree->init_rodata); > + execmem_free(initfree->init_text); > + execmem_free(initfree->init_data); > + execmem_free(initfree->init_rodata); > kfree(initfree); > } > } > @@ -2608,10 +2599,10 @@ static noinline int do_init_module(struct module *mod) > * We want to free module_init, but be aware that kallsyms may be > * walking this with preempt disabled. In all the failure paths, we > * call synchronize_rcu(), but we don't want to slow down the success > - * path. module_memfree() cannot be called in an interrupt, so do the > + * path. execmem_free() cannot be called in an interrupt, so do the > * work and call synchronize_rcu() in a work queue. > * > - * Note that module_alloc() on most architectures creates W+X page > + * Note that execmem_alloc() on most architectures creates W+X page > * mappings which won't be cleaned up until do_free_init() runs. Any > * code such as mark_rodata_ro() which depends on those mappings to > * be cleaned up needs to sync with the queued work by invoking > diff --git a/mm/Kconfig b/mm/Kconfig > index b1448aa81e15..f08a216d4793 100644 > --- a/mm/Kconfig > +++ b/mm/Kconfig > @@ -1241,6 +1241,9 @@ config LOCK_MM_AND_FIND_VMA > config IOMMU_MM_DATA > bool > > +config EXECMEM > + bool > + > source "mm/damon/Kconfig" > > endmenu > diff --git a/mm/Makefile b/mm/Makefile > index 4abb40b911ec..001336c91864 100644 > --- a/mm/Makefile > +++ b/mm/Makefile > @@ -133,3 +133,4 @@ obj-$(CONFIG_IO_MAPPING) += io-mapping.o > obj-$(CONFIG_HAVE_BOOTMEM_INFO_NODE) += bootmem_info.o > obj-$(CONFIG_GENERIC_IOREMAP) += ioremap.o > obj-$(CONFIG_SHRINKER_DEBUG) += shrinker_debug.o > +obj-$(CONFIG_EXECMEM) += execmem.o > diff --git a/mm/execmem.c b/mm/execmem.c > new file mode 100644 > index 000000000000..ed2ea41a2543 > --- /dev/null > +++ b/mm/execmem.c > @@ -0,0 +1,26 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include > +#include > +#include > +#include > + > +static void *__execmem_alloc(size_t size) > +{ > + return module_alloc(size); > +} > + > +void *execmem_alloc(enum execmem_type type, size_t size) > +{ > + return __execmem_alloc(size); > +} > + > +void execmem_free(void *ptr) > +{ > + /* > + * This memory may be RO, and freeing RO memory in an interrupt is not > + * supported by vmalloc. > + */ > + WARN_ON(in_interrupt()); > + vfree(ptr); > +} > -- > 2.43.0 > > -- Masami Hiramatsu (Google)