x86/boot/compressed: Move startup32_check_sev_cbit() out of head_64.S
authorArd Biesheuvel <ardb@kernel.org>
Tue, 22 Nov 2022 16:10:14 +0000 (17:10 +0100)
committerBorislav Petkov <bp@suse.de>
Thu, 24 Nov 2022 07:57:41 +0000 (08:57 +0100)
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
arch/x86/boot/compressed/head_64.S
arch/x86/boot/compressed/mem_encrypt.S

index 30ba541..db577fb 100644 (file)
@@ -711,77 +711,6 @@ SYM_DATA_START(boot_idt)
 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
  */
        .bss
index 6747e5e..14cf04a 100644 (file)
@@ -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"