From: Joerg Roedel <jroe...@suse.de>

This boot path needs exception handling when it is used with SEV-ES.
Setup an IDT and provide a helper function to write IDT entries for
use in 32-bit protected mode.

Signed-off-by: Joerg Roedel <jroe...@suse.de>
---
 arch/x86/boot/compressed/head_64.S | 72 ++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/arch/x86/boot/compressed/head_64.S 
b/arch/x86/boot/compressed/head_64.S
index c59c80ca546d..2001c3bf0748 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -116,6 +116,9 @@ SYM_FUNC_START(startup_32)
        lretl
 1:
 
+       /* Setup Exception handling for SEV-ES */
+       call    startup32_load_idt
+
        /* Make sure cpu supports long mode. */
        call    verify_cpu
        testl   %eax, %eax
@@ -701,6 +704,19 @@ SYM_DATA_START(boot_idt)
        .endr
 SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
 
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+SYM_DATA_START(boot32_idt_desc)
+       .word   boot32_idt_end - boot32_idt - 1
+       .long   0
+SYM_DATA_END(boot32_idt_desc)
+       .balign 8
+SYM_DATA_START(boot32_idt)
+       .rept 32
+       .quad 0
+       .endr
+SYM_DATA_END_LABEL(boot32_idt, SYM_L_GLOBAL, boot32_idt_end)
+#endif
+
 #ifdef CONFIG_EFI_STUB
 SYM_DATA(image_offset, .long 0)
 #endif
@@ -793,6 +809,62 @@ SYM_DATA_START_LOCAL(loaded_image_proto)
 SYM_DATA_END(loaded_image_proto)
 #endif
 
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+       __HEAD
+       .code32
+/*
+ * Write an IDT entry into boot32_idt
+ *
+ * Parameters:
+ *
+ * %eax:       Handler address
+ * %edx:       Vector number
+ *
+ * Physical offset is expected in %ebp
+ */
+SYM_FUNC_START(startup32_set_idt_entry)
+       push    %ebx
+       push    %ecx
+
+       /* IDT entry address to %ebx */
+       leal    rva(boot32_idt)(%ebp), %ebx
+       shl     $3, %edx
+       addl    %edx, %ebx
+
+       /* Build IDT entry, lower 4 bytes */
+       movl    %eax, %edx
+       andl    $0x0000ffff, %edx       # Target code segment offset [15:0]
+       movl    $__KERNEL32_CS, %ecx    # Target code segment selector
+       shl     $16, %ecx
+       orl     %ecx, %edx
+
+       /* Store lower 4 bytes to IDT */
+       movl    %edx, (%ebx)
+
+       /* Build IDT entry, upper 4 bytes */
+       movl    %eax, %edx
+       andl    $0xffff0000, %edx       # Target code segment offset [31:16]
+       orl     $0x00008e00, %edx       # Present, Type 32-bit Interrupt Gate
+
+       /* Store upper 4 bytes to IDT */
+       movl    %edx, 4(%ebx)
+
+       pop     %ecx
+       pop     %ebx
+       ret
+SYM_FUNC_END(startup32_set_idt_entry)
+#endif
+
+SYM_FUNC_START(startup32_load_idt)
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+       /* Load IDT */
+       leal    rva(boot32_idt)(%ebp), %eax
+       movl    %eax, rva(boot32_idt_desc+2)(%ebp)
+       lidt    rva(boot32_idt_desc)(%ebp)
+#endif
+       ret
+SYM_FUNC_END(startup32_load_idt)
+
 /*
  * Stack and heap for uncompression
  */
-- 
2.30.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to