All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb@kernel.org>
To: linux-efi@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel <ardb@kernel.org>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Ingo Molnar <mingo@redhat.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
Subject: [PATCH v9 12/23] x86/decompressor: Call trampoline directly from C code
Date: Mon,  7 Aug 2023 18:27:09 +0200	[thread overview]
Message-ID: <20230807162720.545787-13-ardb@kernel.org> (raw)
In-Reply-To: <20230807162720.545787-1-ardb@kernel.org>

Instead of returning to the asm calling code to invoke the trampoline,
call it straight from the C code that sets it up. That way, the struct
return type is no longer needed for returning two values, and the call
can be made conditional more cleanly in a subsequent patch.

This means that all callee save 64-bit registers need to be preserved
and restored, as their contents may not survive the legacy mode switch.

Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/boot/compressed/head_64.S    | 31 ++++++++-----------
 arch/x86/boot/compressed/pgtable_64.c | 32 ++++++++------------
 2 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 37fd7b7d683d696c..cd6e3e175389aa6b 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -430,25 +430,14 @@ SYM_CODE_START(startup_64)
 #endif
 
 	/*
-	 * paging_prepare() sets up the trampoline and checks if we need to
-	 * enable 5-level paging.
-	 *
-	 * paging_prepare() returns a two-quadword structure which lands
-	 * into RDX:RAX:
-	 *   - Address of the trampoline is returned in RAX.
-	 *   - Non zero RDX means trampoline needs to enable 5-level
-	 *     paging.
+	 * configure_5level_paging() updates the number of paging levels using
+	 * a trampoline in 32-bit addressable memory if the current number does
+	 * not match the desired number.
 	 *
 	 * Pass the boot_params pointer as the first argument.
 	 */
 	movq	%r15, %rdi
-	call	paging_prepare
-
-	/* Pass the trampoline address and boolean flag as args #1 and #2 */
-	movq	%rax, %rdi
-	movq	%rdx, %rsi
-	leaq	TRAMPOLINE_32BIT_CODE_OFFSET(%rax), %rax
-	call	*%rax
+	call	configure_5level_paging
 
 	/*
 	 * cleanup_trampoline() would restore trampoline memory.
@@ -543,11 +532,14 @@ SYM_FUNC_END(.Lrelocated)
 	.section ".rodata", "a", @progbits
 SYM_CODE_START(trampoline_32bit_src)
 	/*
-	 * Preserve live 64-bit registers on the stack: this is necessary
-	 * because the architecture does not guarantee that GPRs will retain
-	 * their full 64-bit values across a 32-bit mode switch.
+	 * Preserve callee save 64-bit registers on the stack: this is
+	 * necessary because the architecture does not guarantee that GPRs will
+	 * retain their full 64-bit values across a 32-bit mode switch.
 	 */
 	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
 	pushq	%rbp
 	pushq	%rbx
 
@@ -574,6 +566,9 @@ SYM_CODE_START(trampoline_32bit_src)
 	/* Restore the preserved 64-bit registers */
 	popq	%rbx
 	popq	%rbp
+	popq	%r12
+	popq	%r13
+	popq	%r14
 	popq	%r15
 	retq
 
diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c
index 5198a05aefa8d14a..f9cc86b2ee55ca80 100644
--- a/arch/x86/boot/compressed/pgtable_64.c
+++ b/arch/x86/boot/compressed/pgtable_64.c
@@ -16,11 +16,6 @@ unsigned int __section(".data") pgdir_shift = 39;
 unsigned int __section(".data") ptrs_per_p4d = 1;
 #endif
 
-struct paging_config {
-	unsigned long trampoline_start;
-	unsigned long l5_required;
-};
-
 /* Buffer to preserve trampoline memory */
 static char trampoline_save[TRAMPOLINE_32BIT_SIZE];
 
@@ -29,7 +24,7 @@ static char trampoline_save[TRAMPOLINE_32BIT_SIZE];
  * purposes.
  *
  * Avoid putting the pointer into .bss as it will be cleared between
- * paging_prepare() and extract_kernel().
+ * configure_5level_paging() and extract_kernel().
  */
 unsigned long *trampoline_32bit __section(".data");
 
@@ -106,13 +101,13 @@ static unsigned long find_trampoline_placement(void)
 	return bios_start - TRAMPOLINE_32BIT_SIZE;
 }
 
-struct paging_config paging_prepare(void *rmode)
+asmlinkage void configure_5level_paging(struct boot_params *bp)
 {
-	struct paging_config paging_config = {};
-	void *tramp_code;
+	void (*toggle_la57)(void *trampoline, bool enable_5lvl);
+	bool l5_required = false;
 
 	/* Initialize boot_params. Required for cmdline_find_option_bool(). */
-	boot_params = rmode;
+	boot_params = bp;
 
 	/*
 	 * Check if LA57 is desired and supported.
@@ -130,7 +125,7 @@ struct paging_config paging_prepare(void *rmode)
 			!cmdline_find_option_bool("no5lvl") &&
 			native_cpuid_eax(0) >= 7 &&
 			(native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) {
-		paging_config.l5_required = 1;
+		l5_required = true;
 
 		/* Initialize variables for 5-level paging */
 		__pgtable_l5_enabled = 1;
@@ -138,9 +133,7 @@ struct paging_config paging_prepare(void *rmode)
 		ptrs_per_p4d = 512;
 	}
 
-	paging_config.trampoline_start = find_trampoline_placement();
-
-	trampoline_32bit = (unsigned long *)paging_config.trampoline_start;
+	trampoline_32bit = (unsigned long *)find_trampoline_placement();
 
 	/* Preserve trampoline memory */
 	memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE);
@@ -149,7 +142,7 @@ struct paging_config paging_prepare(void *rmode)
 	memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE);
 
 	/* Copy trampoline code in place */
-	tramp_code = memcpy(trampoline_32bit +
+	toggle_la57 = memcpy(trampoline_32bit +
 			TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long),
 			&trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE);
 
@@ -159,7 +152,8 @@ struct paging_config paging_prepare(void *rmode)
 	 * immediate absolute address, which needs to be adjusted based on the
 	 * placement of the trampoline.
 	 */
-	*(u32 *)(tramp_code + trampoline_ljmp_imm_offset) += (unsigned long)tramp_code;
+	*(u32 *)((u8 *)toggle_la57 + trampoline_ljmp_imm_offset) +=
+						(unsigned long)toggle_la57;
 
 	/*
 	 * The code below prepares page table in trampoline memory.
@@ -175,10 +169,10 @@ struct paging_config paging_prepare(void *rmode)
 	 * We are not going to use the page table in trampoline memory if we
 	 * are already in the desired paging mode.
 	 */
-	if (paging_config.l5_required == !!(native_read_cr4() & X86_CR4_LA57))
+	if (l5_required == !!(native_read_cr4() & X86_CR4_LA57))
 		goto out;
 
-	if (paging_config.l5_required) {
+	if (l5_required) {
 		/*
 		 * For 4- to 5-level paging transition, set up current CR3 as
 		 * the first and the only entry in a new top-level page table.
@@ -201,7 +195,7 @@ struct paging_config paging_prepare(void *rmode)
 	}
 
 out:
-	return paging_config;
+	toggle_la57(trampoline_32bit, l5_required);
 }
 
 void cleanup_trampoline(void *pgtable)
-- 
2.39.2


  parent reply	other threads:[~2023-08-07 16:28 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-07 16:26 [PATCH v9 00/23] efi/x86: Avoid bare metal decompressor during EFI boot Ard Biesheuvel
2023-08-07 16:26 ` [PATCH v9 01/23] x86/decompressor: Don't rely on upper 32 bits of GPRs being preserved Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:26 ` [PATCH v9 02/23] x86/head_64: Store boot_params pointer in callee save register Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 03/23] x86/efistub: Branch straight to kernel entry point from C code Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 04/23] x86/efistub: Simplify and clean up handover entry code Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 05/23] x86/decompressor: Avoid magic offsets for EFI handover entrypoint Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 06/23] x86/efistub: Clear BSS in EFI handover protocol entrypoint Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 07/23] x86/decompressor: Store boot_params pointer in callee save register Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 08/23] x86/decompressor: Assign paging related global variables earlier Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 09/23] x86/decompressor: Call trampoline as a normal function Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 10/23] x86/decompressor: Use standard calling convention for trampoline Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 11/23] x86/decompressor: Avoid the need for a stack in the 32-bit trampoline Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` Ard Biesheuvel [this message]
2023-08-08  8:44   ` [tip: x86/boot] x86/decompressor: Call trampoline directly from C code tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 13/23] x86/decompressor: Only call the trampoline when changing paging levels Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 14/23] x86/decompressor: Pass pgtable address to trampoline directly Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 15/23] x86/decompressor: Merge trampoline cleanup with switching code Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 16/23] x86/efistub: Perform 4/5 level paging switch from the stub Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 17/23] x86/efistub: Prefer EFI memory attributes protocol over DXE services Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 18/23] decompress: Use 8 byte alignment Ard Biesheuvel
2023-08-08  8:44   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 19/23] x86/decompressor: Move global symbol references to C code Ard Biesheuvel
2023-08-08  8:43   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 20/23] x86/decompressor: Factor out kernel decompression and relocation Ard Biesheuvel
2023-08-08  8:43   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 21/23] efi/libstub: Add limit argument to efi_random_alloc() Ard Biesheuvel
2023-08-08  8:43   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 22/23] x86/efistub: Perform SNP feature test while running in the firmware Ard Biesheuvel
2023-08-08  8:43   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2023-08-07 16:27 ` [PATCH v9 23/23] x86/efistub: Avoid legacy decompressor when doing EFI boot Ard Biesheuvel
2023-08-08  8:43   ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230807162720.545787-13-ardb@kernel.org \
    --to=ardb@kernel.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.