From nobody Thu Dec 18 09:44:07 2025 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (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 7DC7322146D for ; Thu, 5 Dec 2024 15:34:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733412846; cv=none; b=rsuloM3EWdTQUwfZ/ZefF6B106hSGAe577F52NO8uiGSnuY+9OInbYO4dRmZEdTzQhGraysh7HeUOTvAv7eQVN7Joh+ImkBAoenS4f5GZzLJ15r1dNPGPINyo6XvEm6v++kMMNDsbAGQFmRs/lGYdO48p/XNzDgF+fExHpoX7Y4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733412846; c=relaxed/simple; bh=U7KqAkM+73mi46405H+48k5Uu6PkLzIqZ4dmY4aEvLM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UcFsiJCHXhTm2Pc6WBurGlc4KeOfI7IEBatugZ8kMoDk4mBgLba97xCcoi4mbYOzTuvDlKqnLHQIAnp4aFKJtaK7qDFi3mkWtjGsjJvIEaZHD2SQRPROTDOH4+xOrkL3J3vCSjQYppU+9M0GqpmSh3xCjrPu/3ii4tk6Jx4GPYA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=casper.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=EANZkHbR; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=casper.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="EANZkHbR" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=khfTZJiJrlQc2+T6m9tSfcAmQEA7ac5eI6nmkzjnaik=; b=EANZkHbRL2VHSUfb+1K2sjYi5B vG2Q/oU/NKzBEHljMTIe0TaGtF01TNVztQKMN1tKFjzK7SKfSH/bQftTkQnvNxX/lSSzFiL4fPk0I qJePTTN1q86ymCKSxscKOxtXNAgv+nj+TtdYGztttJIkn60ru9zxd/c5PBojebANFuP429pMgea01 FbHBVwMSNGwi+mlqLA8gZsU2//ehTSPoSAY6HbjKMFgVi1Lck1ppJOM0I1KVJ4A98q79LQJ5evsNV GOeWo4/Ypzpd4TgBFfaY070caKFdlZ72ZF0EZNY9IgAkcJTANa1J4zMrGawymPB55gu3QKbvDzXvB OeTHoZ/g==; Received: from [2001:8b0:10b:1::ebe] (helo=i7.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.98 #2 (Red Hat Linux)) id 1tJDrM-0000000DDp4-22s3; Thu, 05 Dec 2024 15:33:45 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.98 #2 (Red Hat Linux)) id 1tJDrN-0000000DyLi-28pf; Thu, 05 Dec 2024 15:33:45 +0000 From: David Woodhouse To: kexec@lists.infradead.org Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , David Woodhouse , "Kirill A. Shutemov" , Kai Huang , Nikolay Borisov , linux-kernel@vger.kernel.org, Simon Horman , Dave Young , Peter Zijlstra , jpoimboe@kernel.org, bsz@amazon.de Subject: [PATCH v5 08/20] x86/kexec: Move relocate_kernel to kernel .data section Date: Thu, 5 Dec 2024 15:05:14 +0000 Message-ID: <20241205153343.3275139-9-dwmw2@infradead.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241205153343.3275139-1-dwmw2@infradead.org> References: <20241205153343.3275139-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse Now that the copy is executed instead of the original, the relocate_kernel page can live in the kernel's .text section. This will allow subsequent commits to actually add real data to it and clean up the code somewhat as well as making the control page ROX. Signed-off-by: David Woodhouse --- arch/x86/include/asm/sections.h | 1 + arch/x86/kernel/callthunks.c | 6 ++++++ arch/x86/kernel/machine_kexec_64.c | 4 +++- arch/x86/kernel/relocate_kernel_64.S | 7 +------ arch/x86/kernel/vmlinux.lds.S | 15 ++++++++++++++- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/section= s.h index 3fa87e5e11ab..30e8ee7006f9 100644 --- a/arch/x86/include/asm/sections.h +++ b/arch/x86/include/asm/sections.h @@ -5,6 +5,7 @@ #include #include =20 +extern char __relocate_kernel_start[], __relocate_kernel_end[]; extern char __brk_base[], __brk_limit[]; extern char __end_rodata_aligned[]; =20 diff --git a/arch/x86/kernel/callthunks.c b/arch/x86/kernel/callthunks.c index 465647456753..51c3e0049152 100644 --- a/arch/x86/kernel/callthunks.c +++ b/arch/x86/kernel/callthunks.c @@ -139,9 +139,15 @@ static bool skip_addr(void *dest) return true; #endif #ifdef CONFIG_KEXEC_CORE +# ifdef CONFIG_X86_64 + if (dest >=3D (void *)__relocate_kernel_start && + dest < (void *)__relocate_kernel_end) + return true; +# else if (dest >=3D (void *)relocate_kernel && dest < (void*)relocate_kernel + KEXEC_CONTROL_CODE_MAX_SIZE) return true; +# endif #endif #ifdef CONFIG_XEN if (dest >=3D (void *)hypercall_page && diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_k= exec_64.c index 9567347f7a9b..23dffdc070dd 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -307,6 +307,8 @@ static void load_segments(void) int machine_kexec_prepare(struct kimage *image) { void *control_page =3D page_address(image->control_code_page); + unsigned long reloc_start =3D (unsigned long)__relocate_kernel_start; + unsigned long reloc_end =3D (unsigned long)__relocate_kernel_end; int result; =20 /* Setup the identity mapped 64bit page table */ @@ -314,7 +316,7 @@ int machine_kexec_prepare(struct kimage *image) if (result) return result; =20 - __memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE); + __memcpy(control_page, __relocate_kernel_start, reloc_end - reloc_start); =20 set_memory_x((unsigned long)control_page, 1); =20 diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocat= e_kernel_64.S index b48bd82843fd..01138f862c59 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -41,10 +41,8 @@ #define CP_PA_BACKUP_PAGES_MAP DATA(0x30) #define CP_VA_CONTROL_PAGE DATA(0x38) =20 - .text - .align PAGE_SIZE + .section .text.relocate_kernel,"ax"; .code64 -SYM_CODE_START_NOALIGN(relocate_range) SYM_CODE_START_NOALIGN(relocate_kernel) UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR @@ -341,6 +339,3 @@ SYM_CODE_START_LOCAL_NOALIGN(swap_pages) ret int3 SYM_CODE_END(swap_pages) - - .skip KEXEC_CONTROL_CODE_MAX_SIZE - (. - relocate_kernel), 0xcc -SYM_CODE_END(relocate_range); diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index fab3ac9a4574..17ebaa441e87 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -28,6 +28,7 @@ #include #include #include +#include =20 #undef i386 /* in case the preprocessor is a 32bit one */ =20 @@ -95,7 +96,18 @@ const_pcpu_hot =3D pcpu_hot; #define BSS_DECRYPTED =20 #endif - +#if defined(CONFIG_X86_64) && defined(CONFIG_KEXEC_CORE) +#define KEXEC_RELOCATE_KERNEL \ + . =3D ALIGN(0x100); \ + __relocate_kernel_start =3D .; \ + *(.text.relocate_kernel); \ + __relocate_kernel_end =3D .; + +ASSERT(__relocate_kernel_end - __relocate_kernel_start <=3D KEXEC_CONTROL_= CODE_MAX_SIZE, + "relocate_kernel code too large!") +#else +#define KEXEC_RELOCATE_KERNEL +#endif PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(6); /* RW_ */ @@ -181,6 +193,7 @@ SECTIONS =20 DATA_DATA CONSTRUCTORS + KEXEC_RELOCATE_KERNEL =20 /* rarely changed data like cpu maps */ READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES) --=20 2.47.0