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 <ardb@kernel.org> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lore.kernel.org/r/20221122161017.2426828-15-ardb@kernel.org
This commit is contained in:
Родитель
b5d854cd4b
Коммит
9d7eaae6a0
|
@ -710,77 +710,6 @@ SYM_DATA_START(boot_idt)
|
|||
.endr
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -243,6 +243,74 @@ SYM_FUNC_START(startup32_load_idt)
|
|||
RET
|
||||
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
|
||||
|
||||
#include "../../kernel/sev_verify_cbit.S"
|
||||
|
|
Загрузка…
Ссылка в новой задаче