From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B4EFC2D0E4 for ; Fri, 20 Nov 2020 20:30:16 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 2466A2223F for ; Fri, 20 Nov 2020 20:30:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2466A2223F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id BDBA16B0070; Fri, 20 Nov 2020 15:30:07 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id A82106B0074; Fri, 20 Nov 2020 15:30:07 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8FB9E6B0070; Fri, 20 Nov 2020 15:30:07 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0213.hostedemail.com [216.40.44.213]) by kanga.kvack.org (Postfix) with ESMTP id 3474B6B0071 for ; Fri, 20 Nov 2020 15:30:07 -0500 (EST) Received: from smtpin14.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id CC7B51F0A for ; Fri, 20 Nov 2020 20:30:06 +0000 (UTC) X-FDA: 77505938412.14.knife00_2e0d9e42734e Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin14.hostedemail.com (Postfix) with ESMTP id AAE2818229818 for ; Fri, 20 Nov 2020 20:30:06 +0000 (UTC) X-HE-Tag: knife00_2e0d9e42734e X-Filterd-Recvd-Size: 7227 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by imf32.hostedemail.com (Postfix) with ESMTP for ; Fri, 20 Nov 2020 20:30:05 +0000 (UTC) IronPort-SDR: QM2d1GcdYEDU8FtVanW08p4t0pgjNEb2R2KZbKG2lrJjGc4Xa7KPxglqVT7Mfl47doGR2Aiwao FpTRiJhTgxow== X-IronPort-AV: E=McAfee;i="6000,8403,9811"; a="171702869" X-IronPort-AV: E=Sophos;i="5.78,357,1599548400"; d="scan'208";a="171702869" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Nov 2020 12:30:03 -0800 IronPort-SDR: II4ekpkhOvKaWBqJedqpw9lKC/FogA54M5cqtk2mIsaXaaDR8zAXkVs+TgD+DICnZJ3XUcjpCg sq9q0khmZD0w== X-IronPort-AV: E=Sophos;i="5.78,357,1599548400"; d="scan'208";a="342163300" Received: from rpedgeco-mobl.amr.corp.intel.com (HELO localhost.intel.com) ([10.209.105.214]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Nov 2020 12:30:02 -0800 From: Rick Edgecombe To: akpm@linux-foundation.org, jeyu@kernel.org, bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, luto@kernel.org, dave.hansen@linux.intel.com, peterz@infradead.org, x86@kernel.org, rppt@kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com Cc: elena.reshetova@intel.com, ira.weiny@intel.com, Rick Edgecombe Subject: [PATCH RFC 05/10] x86/modules: Use real perm_allocations Date: Fri, 20 Nov 2020 12:24:21 -0800 Message-Id: <20201120202426.18009-6-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201120202426.18009-1-rick.p.edgecombe@intel.com> References: <20201120202426.18009-1-rick.p.edgecombe@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: x86 relocations require all of the text sections to be within 2GB of eachother. So as long as the allocations are somewhere in the module area= , relocations can be applied. So relax the restriction of having the module regions for a module core or init area be virtually contiguous. Also, apply relocations at the writable address of the perm_allocation to support a future implementation that has the writable address in a different allocation. Signed-off-by: Rick Edgecombe --- arch/x86/kernel/module.c | 84 +++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 34b153cbd4ac..7b369f5ffdb7 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -85,6 +85,58 @@ void *module_alloc(unsigned long size) return p; } =20 +bool module_perm_alloc(struct module_layout *layout) +{ + unsigned long vstart =3D MODULES_VADDR + get_module_load_offset(); + unsigned long vend =3D MODULES_END; + unsigned int text_page_cnt =3D PAGE_ALIGN(layout->text.size) >> PAGE_SH= IFT; + unsigned int ro_page_cnt =3D PAGE_ALIGN(layout->ro.size) >> PAGE_SHIFT; + unsigned int ro_after_init_page_cnt =3D PAGE_ALIGN(layout->ro_after_ini= t.size) >> PAGE_SHIFT; + unsigned int rw_page_cnt =3D PAGE_ALIGN(layout->rw.size) >> PAGE_SHIFT; + + layout->text.alloc =3D NULL; + layout->ro.alloc =3D NULL; + layout->ro_after_init.alloc =3D NULL; + layout->rw.alloc =3D NULL; + + layout->text.alloc =3D perm_alloc(vstart, vend, text_page_cnt, PERM_RX)= ; + if (!layout->text.alloc && layout->text.size) + goto out; + + layout->ro.alloc =3D perm_alloc(vstart, vend, ro_page_cnt, PERM_R); + if (!layout->ro.alloc && layout->ro.size) + goto text_free_out; + + layout->ro_after_init.alloc =3D perm_alloc(vstart, vend, ro_after_init_= page_cnt, PERM_RW); + if (!layout->ro_after_init.alloc && layout->ro_after_init.size) + goto ro_free_out; + + layout->rw.alloc =3D perm_alloc(vstart, vend, rw_page_cnt, PERM_RW); + if (!layout->rw.alloc && layout->rw.size) + goto ro_after_init_out; + + return true; +ro_after_init_out: + perm_free(layout->ro_after_init.alloc); + layout->ro_after_init.alloc =3D NULL; +ro_free_out: + perm_free(layout->ro.alloc); + layout->ro.alloc =3D NULL; +text_free_out: + perm_free(layout->text.alloc); + layout->text.alloc =3D NULL; +out: + return false; +} + +void module_perm_free(struct module_layout *layout) +{ + perm_free(layout->text.alloc); + perm_free(layout->ro.alloc); + perm_free(layout->ro_after_init.alloc); + perm_free(layout->rw.alloc); +} + #ifdef CONFIG_X86_32 int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, @@ -134,9 +186,11 @@ static int __apply_relocate_add(Elf64_Shdr *sechdrs, void *(*write)(void *dest, const void *src, size_t len)) { unsigned int i; + struct perm_allocation *alloc; Elf64_Rela *rel =3D (void *)sechdrs[relsec].sh_addr; Elf64_Sym *sym; void *loc; + void *writable_loc; u64 val; =20 DEBUGP("Applying relocate section %u to %u\n", @@ -146,6 +200,9 @@ static int __apply_relocate_add(Elf64_Shdr *sechdrs, loc =3D (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset; =20 + alloc =3D module_get_allocation(me, (unsigned long)loc); + writable_loc =3D (void *)perm_writable_addr(alloc, (unsigned long)loc)= ; + /* This is the symbol it is referring to. Note that all undefined symbols have been resolved. */ sym =3D (Elf64_Sym *)sechdrs[symindex].sh_addr @@ -161,40 +218,40 @@ static int __apply_relocate_add(Elf64_Shdr *sechdrs= , case R_X86_64_NONE: break; case R_X86_64_64: - if (*(u64 *)loc !=3D 0) + if (*(u64 *)writable_loc !=3D 0) goto invalid_relocation; - write(loc, &val, 8); + write(writable_loc, &val, 8); break; case R_X86_64_32: - if (*(u32 *)loc !=3D 0) + if (*(u32 *)writable_loc !=3D 0) goto invalid_relocation; - write(loc, &val, 4); - if (val !=3D *(u32 *)loc) + write(writable_loc, &val, 4); + if (val !=3D *(u32 *)writable_loc) goto overflow; break; case R_X86_64_32S: - if (*(s32 *)loc !=3D 0) + if (*(s32 *)writable_loc !=3D 0) goto invalid_relocation; - write(loc, &val, 4); - if ((s64)val !=3D *(s32 *)loc) + write(writable_loc, &val, 4); + if ((s64)val !=3D *(s32 *)writable_loc) goto overflow; break; case R_X86_64_PC32: case R_X86_64_PLT32: - if (*(u32 *)loc !=3D 0) + if (*(u32 *)writable_loc !=3D 0) goto invalid_relocation; val -=3D (u64)loc; - write(loc, &val, 4); + write(writable_loc, &val, 4); #if 0 - if ((s64)val !=3D *(s32 *)loc) + if ((s64)val !=3D *(s32 *)writable_loc) goto overflow; #endif break; case R_X86_64_PC64: - if (*(u64 *)loc !=3D 0) + if (*(u64 *)writable_loc !=3D 0) goto invalid_relocation; val -=3D (u64)loc; - write(loc, &val, 8); + write(writable_loc, &val, 8); break; default: pr_err("%s: Unknown rela relocation: %llu\n", @@ -273,6 +330,7 @@ int module_finalize(const Elf_Ehdr *hdr, void *aseg =3D (void *)alt->sh_addr; apply_alternatives(aseg, aseg + alt->sh_size); } + if (locks && text) { void *lseg =3D (void *)locks->sh_addr; void *tseg =3D (void *)text->sh_addr; --=20 2.20.1