[PATCH] x86/boot: Clean up handling of boot_params pointer

From: Brian Gerst
Date: Fri Mar 31 2023 - 14:29:07 EST


On entry from the bootloader, RSI contains the pointer to the
boot_params data structure. Since the RSI register can be clobbered
when calling C functions, it is saved and restored around every call.
Instead, move it to the R12 register, which is preserved across calls.

Signed-off-by: Brian Gerst <brgerst@xxxxxxxxx>
---
arch/x86/kernel/head_64.S | 29 ++++++++++-------------------
1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index a5df3e994f04..0d130ca2e0a3 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -49,8 +49,6 @@ 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.
- *
* We come here either directly from a 64bit bootloader, or from
* arch/x86/boot/compressed/head_64.S.
*
@@ -61,6 +59,12 @@ SYM_CODE_START_NOALIGN(startup_64)
* tables and then reload them.
*/

+ /*
+ * RSI holds a physical pointer to real_mode_data. Move it to R12,
+ * which is preserved across C function calls.
+ */
+ movq %rsi, %r12
+
/* Set up the stack for verify_cpu() */
leaq (__end_init_task - PTREGS_SIZE)(%rip), %rsp

@@ -73,9 +77,7 @@ SYM_CODE_START_NOALIGN(startup_64)
shrq $32, %rdx
wrmsr

- pushq %rsi
call startup_64_setup_env
- popq %rsi

#ifdef CONFIG_AMD_MEM_ENCRYPT
/*
@@ -84,10 +86,8 @@ SYM_CODE_START_NOALIGN(startup_64)
* which needs to be done before any CPUID instructions are executed in
* subsequent code.
*/
- movq %rsi, %rdi
- pushq %rsi
+ movq %r12, %rdi
call sme_enable
- popq %rsi
#endif

/* Now switch to __KERNEL_CS so IRET works reliably */
@@ -109,9 +109,8 @@ SYM_CODE_START_NOALIGN(startup_64)
* programmed into CR3.
*/
leaq _text(%rip), %rdi
- pushq %rsi
+ movq %r12, %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
@@ -125,8 +124,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).
*
@@ -197,13 +194,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
@@ -294,9 +287,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
@@ -332,9 +323,9 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
pushq $0
popfq

- /* rsi is pointer to real mode structure with interesting info.
+ /* R12 is pointer to real mode structure with interesting info.
pass it to C */
- movq %rsi, %rdi
+ movq %r12, %rdi

.Ljump_to_C_code:
/*
--
2.39.2