Commit 2f69a81a authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Borislav Petkov (AMD)
Browse files

x86/head_64: Store boot_params pointer in callee save register



Instead of pushing/popping %RSI to/from the stack every time a function
is called from startup_64(), store it in a callee preserved register
and grab it from there when its value is actually needed.

Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230807162720.545787-3-ardb@kernel.org
parent 264b82fd
Loading
Loading
Loading
Loading
+12 −20
Original line number Diff line number Diff line
@@ -51,7 +51,9 @@ SYM_CODE_START_NOALIGN(startup_64)
	 * for us.  These identity mapped page tables map all of the
	 * kernel pages and possibly all of memory.
	 *
	 * %rsi holds a physical pointer to real_mode_data.
	 * %RSI holds the physical address of the boot_params structure
	 * provided by the bootloader. Preserve it in %R15 so C function calls
	 * will not clobber it.
	 *
	 * We come here either directly from a 64bit bootloader, or from
	 * arch/x86/boot/compressed/head_64.S.
@@ -62,6 +64,7 @@ SYM_CODE_START_NOALIGN(startup_64)
	 * compiled to run at we first fixup the physical addresses in our page
	 * tables and then reload them.
	 */
	mov	%rsi, %r15

	/* Set up the stack for verify_cpu() */
	leaq	(__end_init_task - PTREGS_SIZE)(%rip), %rsp
@@ -75,9 +78,7 @@ SYM_CODE_START_NOALIGN(startup_64)
	shrq	$32,  %rdx
	wrmsr

	pushq	%rsi
	call	startup_64_setup_env
	popq	%rsi

	/* Now switch to __KERNEL_CS so IRET works reliably */
	pushq	$__KERNEL_CS
@@ -93,12 +94,10 @@ SYM_CODE_START_NOALIGN(startup_64)
	 * Activate SEV/SME memory encryption if supported/enabled. This needs to
	 * be done now, since this also includes setup of the SEV-SNP CPUID table,
	 * which needs to be done before any CPUID instructions are executed in
	 * subsequent code.
	 * subsequent code. Pass the boot_params pointer as the first argument.
	 */
	movq	%rsi, %rdi
	pushq	%rsi
	movq	%r15, %rdi
	call	sme_enable
	popq	%rsi
#endif

	/* Sanitize CPU configuration */
@@ -111,9 +110,8 @@ SYM_CODE_START_NOALIGN(startup_64)
	 * programmed into CR3.
	 */
	leaq	_text(%rip), %rdi
	pushq	%rsi
	movq	%r15, %rsi
	call	__startup_64
	popq	%rsi

	/* Form the CR3 value being sure to include the CR3 modifier */
	addq	$(early_top_pgt - __START_KERNEL_map), %rax
@@ -127,8 +125,6 @@ SYM_CODE_START(secondary_startup_64)
	 * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0,
	 * and someone has loaded a mapped page table.
	 *
	 * %rsi holds a physical pointer to real_mode_data.
	 *
	 * We come here either from startup_64 (using physical addresses)
	 * or from trampoline.S (using virtual addresses).
	 *
@@ -153,6 +149,9 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
	UNWIND_HINT_END_OF_STACK
	ANNOTATE_NOENDBR

	/* Clear %R15 which holds the boot_params pointer on the boot CPU */
	xorq	%r15, %r15

	/*
	 * Retrieve the modifier (SME encryption mask if SME is active) to be
	 * added to the initial pgdir entry that will be programmed into CR3.
@@ -199,13 +198,9 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
	 * hypervisor could lie about the C-bit position to perform a ROP
	 * attack on the guest by writing to the unencrypted stack and wait for
	 * the next RET instruction.
	 * %rsi carries pointer to realmode data and is callee-clobbered. Save
	 * and restore it.
	 */
	pushq	%rsi
	movq	%rax, %rdi
	call	sev_verify_cbit
	popq	%rsi

	/*
	 * Switch to new page-table
@@ -365,9 +360,7 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
	wrmsr

	/* Setup and Load IDT */
	pushq	%rsi
	call	early_setup_idt
	popq	%rsi

	/* Check if nx is implemented */
	movl	$0x80000001, %eax
@@ -403,9 +396,8 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
	pushq $0
	popfq

	/* rsi is pointer to real mode structure with interesting info.
	   pass it to C */
	movq	%rsi, %rdi
	/* Pass the boot_params pointer as first argument */
	movq	%r15, %rdi

.Ljump_to_C_code:
	/*