Skip to content

Commit 9d7eaae

Browse files
ardbiesheuvelsuryasaimadhu
authored andcommitted
x86/boot/compressed: Move startup32_check_sev_cbit() out of head_64.S
Now that the startup32_check_sev_cbit() routine can execute from anywhere and behaves like an ordinary function, it can be moved where it belongs. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b5d854c commit 9d7eaae

File tree

2 files changed

+68
-71
lines changed

2 files changed

+68
-71
lines changed

arch/x86/boot/compressed/head_64.S

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -710,77 +710,6 @@ SYM_DATA_START(boot_idt)
710710
.endr
711711
SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
712712

713-
/*
714-
* Check for the correct C-bit position when the startup_32 boot-path is used.
715-
*
716-
* The check makes use of the fact that all memory is encrypted when paging is
717-
* disabled. The function creates 64 bits of random data using the RDRAND
718-
* instruction. RDRAND is mandatory for SEV guests, so always available. If the
719-
* hypervisor violates that the kernel will crash right here.
720-
*
721-
* The 64 bits of random data are stored to a memory location and at the same
722-
* time kept in the %eax and %ebx registers. Since encryption is always active
723-
* when paging is off the random data will be stored encrypted in main memory.
724-
*
725-
* Then paging is enabled. When the C-bit position is correct all memory is
726-
* still mapped encrypted and comparing the register values with memory will
727-
* succeed. An incorrect C-bit position will map all memory unencrypted, so that
728-
* the compare will use the encrypted random data and fail.
729-
*/
730-
#ifdef CONFIG_AMD_MEM_ENCRYPT
731-
.text
732-
SYM_FUNC_START(startup32_check_sev_cbit)
733-
pushl %ebx
734-
pushl %ebp
735-
736-
call 0f
737-
0: popl %ebp
738-
739-
/* Check for non-zero sev_status */
740-
movl (sev_status - 0b)(%ebp), %eax
741-
testl %eax, %eax
742-
jz 4f
743-
744-
/*
745-
* Get two 32-bit random values - Don't bail out if RDRAND fails
746-
* because it is better to prevent forward progress if no random value
747-
* can be gathered.
748-
*/
749-
1: rdrand %eax
750-
jnc 1b
751-
2: rdrand %ebx
752-
jnc 2b
753-
754-
/* Store to memory and keep it in the registers */
755-
leal (sev_check_data - 0b)(%ebp), %ebp
756-
movl %eax, 0(%ebp)
757-
movl %ebx, 4(%ebp)
758-
759-
/* Enable paging to see if encryption is active */
760-
movl %cr0, %edx /* Backup %cr0 in %edx */
761-
movl $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */
762-
movl %ecx, %cr0
763-
764-
cmpl %eax, 0(%ebp)
765-
jne 3f
766-
cmpl %ebx, 4(%ebp)
767-
jne 3f
768-
769-
movl %edx, %cr0 /* Restore previous %cr0 */
770-
771-
jmp 4f
772-
773-
3: /* Check failed - hlt the machine */
774-
hlt
775-
jmp 3b
776-
777-
4:
778-
popl %ebp
779-
popl %ebx
780-
RET
781-
SYM_FUNC_END(startup32_check_sev_cbit)
782-
#endif
783-
784713
/*
785714
* Stack and heap for uncompression
786715
*/

arch/x86/boot/compressed/mem_encrypt.S

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,74 @@ SYM_FUNC_START(startup32_load_idt)
243243
RET
244244
SYM_FUNC_END(startup32_load_idt)
245245

246+
/*
247+
* Check for the correct C-bit position when the startup_32 boot-path is used.
248+
*
249+
* The check makes use of the fact that all memory is encrypted when paging is
250+
* disabled. The function creates 64 bits of random data using the RDRAND
251+
* instruction. RDRAND is mandatory for SEV guests, so always available. If the
252+
* hypervisor violates that the kernel will crash right here.
253+
*
254+
* The 64 bits of random data are stored to a memory location and at the same
255+
* time kept in the %eax and %ebx registers. Since encryption is always active
256+
* when paging is off the random data will be stored encrypted in main memory.
257+
*
258+
* Then paging is enabled. When the C-bit position is correct all memory is
259+
* still mapped encrypted and comparing the register values with memory will
260+
* succeed. An incorrect C-bit position will map all memory unencrypted, so that
261+
* the compare will use the encrypted random data and fail.
262+
*/
263+
SYM_FUNC_START(startup32_check_sev_cbit)
264+
pushl %ebx
265+
pushl %ebp
266+
267+
call 0f
268+
0: popl %ebp
269+
270+
/* Check for non-zero sev_status */
271+
movl (sev_status - 0b)(%ebp), %eax
272+
testl %eax, %eax
273+
jz 4f
274+
275+
/*
276+
* Get two 32-bit random values - Don't bail out if RDRAND fails
277+
* because it is better to prevent forward progress if no random value
278+
* can be gathered.
279+
*/
280+
1: rdrand %eax
281+
jnc 1b
282+
2: rdrand %ebx
283+
jnc 2b
284+
285+
/* Store to memory and keep it in the registers */
286+
leal (sev_check_data - 0b)(%ebp), %ebp
287+
movl %eax, 0(%ebp)
288+
movl %ebx, 4(%ebp)
289+
290+
/* Enable paging to see if encryption is active */
291+
movl %cr0, %edx /* Backup %cr0 in %edx */
292+
movl $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */
293+
movl %ecx, %cr0
294+
295+
cmpl %eax, 0(%ebp)
296+
jne 3f
297+
cmpl %ebx, 4(%ebp)
298+
jne 3f
299+
300+
movl %edx, %cr0 /* Restore previous %cr0 */
301+
302+
jmp 4f
303+
304+
3: /* Check failed - hlt the machine */
305+
hlt
306+
jmp 3b
307+
308+
4:
309+
popl %ebp
310+
popl %ebx
311+
RET
312+
SYM_FUNC_END(startup32_check_sev_cbit)
313+
246314
.code64
247315

248316
#include "../../kernel/sev_verify_cbit.S"

0 commit comments

Comments
 (0)