Skip to content

Commit 2f69a81

Browse files
ardbiesheuvelbp3tk0v
authored andcommitted
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: Ard Biesheuvel <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 264b82f commit 2f69a81

File tree

1 file changed

+12
-20
lines changed

1 file changed

+12
-20
lines changed

arch/x86/kernel/head_64.S

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ SYM_CODE_START_NOALIGN(startup_64)
5151
* for us. These identity mapped page tables map all of the
5252
* kernel pages and possibly all of memory.
5353
*
54-
* %rsi holds a physical pointer to real_mode_data.
54+
* %RSI holds the physical address of the boot_params structure
55+
* provided by the bootloader. Preserve it in %R15 so C function calls
56+
* will not clobber it.
5557
*
5658
* We come here either directly from a 64bit bootloader, or from
5759
* arch/x86/boot/compressed/head_64.S.
@@ -62,6 +64,7 @@ SYM_CODE_START_NOALIGN(startup_64)
6264
* compiled to run at we first fixup the physical addresses in our page
6365
* tables and then reload them.
6466
*/
67+
mov %rsi, %r15
6568

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

78-
pushq %rsi
7981
call startup_64_setup_env
80-
popq %rsi
8182

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

104103
/* Sanitize CPU configuration */
@@ -111,9 +110,8 @@ SYM_CODE_START_NOALIGN(startup_64)
111110
* programmed into CR3.
112111
*/
113112
leaq _text(%rip), %rdi
114-
pushq %rsi
113+
movq %r15, %rsi
115114
call __startup_64
116-
popq %rsi
117115

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

152+
/* Clear %R15 which holds the boot_params pointer on the boot CPU */
153+
xorq %r15, %r15
154+
156155
/*
157156
* Retrieve the modifier (SME encryption mask if SME is active) to be
158157
* 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)
199198
* hypervisor could lie about the C-bit position to perform a ROP
200199
* attack on the guest by writing to the unencrypted stack and wait for
201200
* the next RET instruction.
202-
* %rsi carries pointer to realmode data and is callee-clobbered. Save
203-
* and restore it.
204201
*/
205-
pushq %rsi
206202
movq %rax, %rdi
207203
call sev_verify_cbit
208-
popq %rsi
209204

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

367362
/* Setup and Load IDT */
368-
pushq %rsi
369363
call early_setup_idt
370-
popq %rsi
371364

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

406-
/* rsi is pointer to real mode structure with interesting info.
407-
pass it to C */
408-
movq %rsi, %rdi
399+
/* Pass the boot_params pointer as first argument */
400+
movq %r15, %rdi
409401

410402
.Ljump_to_C_code:
411403
/*

0 commit comments

Comments
 (0)