mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
x86/boot/compressed: Move startup32_check_sev_cbit() out of head_64.S
commit 9d7eaae6a0 upstream.
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 <ardb@kernel.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20221122161017.2426828-15-ardb@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
e840ae3dc2
commit
0912dce9ed
@@ -726,77 +726,6 @@ SYM_DATA_START(boot_idt)
|
|||||||
.endr
|
.endr
|
||||||
SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
|
SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for the correct C-bit position when the startup_32 boot-path is used.
|
|
||||||
*
|
|
||||||
* The check makes use of the fact that all memory is encrypted when paging is
|
|
||||||
* disabled. The function creates 64 bits of random data using the RDRAND
|
|
||||||
* instruction. RDRAND is mandatory for SEV guests, so always available. If the
|
|
||||||
* hypervisor violates that the kernel will crash right here.
|
|
||||||
*
|
|
||||||
* The 64 bits of random data are stored to a memory location and at the same
|
|
||||||
* time kept in the %eax and %ebx registers. Since encryption is always active
|
|
||||||
* when paging is off the random data will be stored encrypted in main memory.
|
|
||||||
*
|
|
||||||
* Then paging is enabled. When the C-bit position is correct all memory is
|
|
||||||
* still mapped encrypted and comparing the register values with memory will
|
|
||||||
* succeed. An incorrect C-bit position will map all memory unencrypted, so that
|
|
||||||
* the compare will use the encrypted random data and fail.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
|
||||||
.text
|
|
||||||
SYM_FUNC_START(startup32_check_sev_cbit)
|
|
||||||
pushl %ebx
|
|
||||||
pushl %ebp
|
|
||||||
|
|
||||||
call 0f
|
|
||||||
0: popl %ebp
|
|
||||||
|
|
||||||
/* Check for non-zero sev_status */
|
|
||||||
movl (sev_status - 0b)(%ebp), %eax
|
|
||||||
testl %eax, %eax
|
|
||||||
jz 4f
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get two 32-bit random values - Don't bail out if RDRAND fails
|
|
||||||
* because it is better to prevent forward progress if no random value
|
|
||||||
* can be gathered.
|
|
||||||
*/
|
|
||||||
1: rdrand %eax
|
|
||||||
jnc 1b
|
|
||||||
2: rdrand %ebx
|
|
||||||
jnc 2b
|
|
||||||
|
|
||||||
/* Store to memory and keep it in the registers */
|
|
||||||
leal (sev_check_data - 0b)(%ebp), %ebp
|
|
||||||
movl %eax, 0(%ebp)
|
|
||||||
movl %ebx, 4(%ebp)
|
|
||||||
|
|
||||||
/* Enable paging to see if encryption is active */
|
|
||||||
movl %cr0, %edx /* Backup %cr0 in %edx */
|
|
||||||
movl $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */
|
|
||||||
movl %ecx, %cr0
|
|
||||||
|
|
||||||
cmpl %eax, 0(%ebp)
|
|
||||||
jne 3f
|
|
||||||
cmpl %ebx, 4(%ebp)
|
|
||||||
jne 3f
|
|
||||||
|
|
||||||
movl %edx, %cr0 /* Restore previous %cr0 */
|
|
||||||
|
|
||||||
jmp 4f
|
|
||||||
|
|
||||||
3: /* Check failed - hlt the machine */
|
|
||||||
hlt
|
|
||||||
jmp 3b
|
|
||||||
|
|
||||||
4:
|
|
||||||
popl %ebp
|
|
||||||
popl %ebx
|
|
||||||
RET
|
|
||||||
SYM_FUNC_END(startup32_check_sev_cbit)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stack and heap for uncompression
|
* Stack and heap for uncompression
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -243,6 +243,74 @@ SYM_FUNC_START(startup32_load_idt)
|
|||||||
RET
|
RET
|
||||||
SYM_FUNC_END(startup32_load_idt)
|
SYM_FUNC_END(startup32_load_idt)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for the correct C-bit position when the startup_32 boot-path is used.
|
||||||
|
*
|
||||||
|
* The check makes use of the fact that all memory is encrypted when paging is
|
||||||
|
* disabled. The function creates 64 bits of random data using the RDRAND
|
||||||
|
* instruction. RDRAND is mandatory for SEV guests, so always available. If the
|
||||||
|
* hypervisor violates that the kernel will crash right here.
|
||||||
|
*
|
||||||
|
* The 64 bits of random data are stored to a memory location and at the same
|
||||||
|
* time kept in the %eax and %ebx registers. Since encryption is always active
|
||||||
|
* when paging is off the random data will be stored encrypted in main memory.
|
||||||
|
*
|
||||||
|
* Then paging is enabled. When the C-bit position is correct all memory is
|
||||||
|
* still mapped encrypted and comparing the register values with memory will
|
||||||
|
* succeed. An incorrect C-bit position will map all memory unencrypted, so that
|
||||||
|
* the compare will use the encrypted random data and fail.
|
||||||
|
*/
|
||||||
|
SYM_FUNC_START(startup32_check_sev_cbit)
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ebp
|
||||||
|
|
||||||
|
call 0f
|
||||||
|
0: popl %ebp
|
||||||
|
|
||||||
|
/* Check for non-zero sev_status */
|
||||||
|
movl (sev_status - 0b)(%ebp), %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
jz 4f
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get two 32-bit random values - Don't bail out if RDRAND fails
|
||||||
|
* because it is better to prevent forward progress if no random value
|
||||||
|
* can be gathered.
|
||||||
|
*/
|
||||||
|
1: rdrand %eax
|
||||||
|
jnc 1b
|
||||||
|
2: rdrand %ebx
|
||||||
|
jnc 2b
|
||||||
|
|
||||||
|
/* Store to memory and keep it in the registers */
|
||||||
|
leal (sev_check_data - 0b)(%ebp), %ebp
|
||||||
|
movl %eax, 0(%ebp)
|
||||||
|
movl %ebx, 4(%ebp)
|
||||||
|
|
||||||
|
/* Enable paging to see if encryption is active */
|
||||||
|
movl %cr0, %edx /* Backup %cr0 in %edx */
|
||||||
|
movl $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */
|
||||||
|
movl %ecx, %cr0
|
||||||
|
|
||||||
|
cmpl %eax, 0(%ebp)
|
||||||
|
jne 3f
|
||||||
|
cmpl %ebx, 4(%ebp)
|
||||||
|
jne 3f
|
||||||
|
|
||||||
|
movl %edx, %cr0 /* Restore previous %cr0 */
|
||||||
|
|
||||||
|
jmp 4f
|
||||||
|
|
||||||
|
3: /* Check failed - hlt the machine */
|
||||||
|
hlt
|
||||||
|
jmp 3b
|
||||||
|
|
||||||
|
4:
|
||||||
|
popl %ebp
|
||||||
|
popl %ebx
|
||||||
|
RET
|
||||||
|
SYM_FUNC_END(startup32_check_sev_cbit)
|
||||||
|
|
||||||
.code64
|
.code64
|
||||||
|
|
||||||
#include "../../kernel/sev_verify_cbit.S"
|
#include "../../kernel/sev_verify_cbit.S"
|
||||||
|
|||||||
Reference in New Issue
Block a user