efi/libstub: x86/mixed: increase supported argument count
authorArd Biesheuvel <ardb@kernel.org>
Fri, 19 Nov 2021 11:47:43 +0000 (13:47 +0200)
committerArd Biesheuvel <ardb@kernel.org>
Sun, 21 Nov 2021 16:08:10 +0000 (17:08 +0100)
Increase the number of arguments supported by mixed mode calls, so that
we will be able to call into the TCG2 protocol to measure the initrd
and extend the associated PCR. This involves the TCG2 protocol's
hash_log_extend_event() method, which takes five arguments, three of
which are u64 and need to be split, producing a total of 8 outgoing

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Link: https://lore.kernel.org/r/20211119114745.1560453-3-ilias.apalodimas@linaro.org
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/x86/boot/compressed/efi_thunk_64.S
arch/x86/include/asm/efi.h
arch/x86/platform/efi/efi_thunk_64.S

index 8bb92e9f4e9739f1d0bf2d77f9fa42b829ed9e7f..d05f781d54f260a1a29b365cc427fefd406c8bfa 100644 (file)
@@ -26,8 +26,6 @@ SYM_FUNC_START(__efi64_thunk)
        push    %rbp
        push    %rbx
 
-       leaq    1f(%rip), %rbp
-
        movl    %ds, %eax
        push    %rax
        movl    %es, %eax
@@ -35,6 +33,11 @@ SYM_FUNC_START(__efi64_thunk)
        movl    %ss, %eax
        push    %rax
 
+       /* Copy args passed on stack */
+       movq    0x30(%rsp), %rbp
+       movq    0x38(%rsp), %rbx
+       movq    0x40(%rsp), %rax
+
        /*
         * Convert x86-64 ABI params to i386 ABI
         */
@@ -44,13 +47,18 @@ SYM_FUNC_START(__efi64_thunk)
        movl    %ecx, 0x8(%rsp)
        movl    %r8d, 0xc(%rsp)
        movl    %r9d, 0x10(%rsp)
+       movl    %ebp, 0x14(%rsp)
+       movl    %ebx, 0x18(%rsp)
+       movl    %eax, 0x1c(%rsp)
 
-       leaq    0x14(%rsp), %rbx
+       leaq    0x20(%rsp), %rbx
        sgdt    (%rbx)
 
        addq    $16, %rbx
        sidt    (%rbx)
 
+       leaq    1f(%rip), %rbp
+
        /*
         * Switch to IDT and GDT with 32-bit segments. This is the firmware GDT
         * and IDT that was installed when the kernel started executing. The
index 85f156f8ef81031bec7d51b2a1ef7339dca7e853..a323dbac9182981c1e44568fcd9c6255a0cae227 100644 (file)
@@ -46,13 +46,14 @@ extern unsigned long efi_mixed_mode_stack_pa;
 
 #define __efi_nargs(...) __efi_nargs_(__VA_ARGS__)
 #define __efi_nargs_(...) __efi_nargs__(0, ##__VA_ARGS__,      \
+       __efi_arg_sentinel(9), __efi_arg_sentinel(8),           \
        __efi_arg_sentinel(7), __efi_arg_sentinel(6),           \
        __efi_arg_sentinel(5), __efi_arg_sentinel(4),           \
        __efi_arg_sentinel(3), __efi_arg_sentinel(2),           \
        __efi_arg_sentinel(1), __efi_arg_sentinel(0))
-#define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, n, ...)  \
+#define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, ...)  \
        __take_second_arg(n,                                    \
-               ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 8; }))
+               ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 10; }))
 #define __efi_arg_sentinel(n) , n
 
 /*
@@ -176,8 +177,9 @@ extern u64 efi_setup;
 extern efi_status_t __efi64_thunk(u32, ...);
 
 #define efi64_thunk(...) ({                                            \
-       __efi_nargs_check(efi64_thunk, 6, __VA_ARGS__);                 \
-       __efi64_thunk(__VA_ARGS__);                                     \
+       u64 __pad[3]; /* must have space for 3 args on the stack */     \
+       __efi_nargs_check(efi64_thunk, 9, __VA_ARGS__);                 \
+       __efi64_thunk(__VA_ARGS__, __pad);                              \
 })
 
 static inline bool efi_is_mixed(void)
index fd3dd1708eba54284d5f2f7e75575704c45a0e9e..5b7c6e09954ec33135ba9d19b780b975dc8f1acc 100644 (file)
@@ -36,6 +36,17 @@ SYM_CODE_START(__efi64_thunk)
        movq    efi_mixed_mode_stack_pa(%rip), %rsp
        push    %rax
 
+       /*
+        * Copy args passed via the stack
+        */
+       subq    $0x24, %rsp
+       movq    0x18(%rax), %rbp
+       movq    0x20(%rax), %rbx
+       movq    0x28(%rax), %rax
+       movl    %ebp, 0x18(%rsp)
+       movl    %ebx, 0x1c(%rsp)
+       movl    %eax, 0x20(%rsp)
+
        /*
         * Calculate the physical address of the kernel text.
         */
@@ -47,7 +58,6 @@ SYM_CODE_START(__efi64_thunk)
        subq    %rax, %rbp
        subq    %rax, %rbx
 
-       subq    $28, %rsp
        movl    %ebx, 0x0(%rsp)         /* return address */
        movl    %esi, 0x4(%rsp)
        movl    %edx, 0x8(%rsp)
@@ -60,7 +70,7 @@ SYM_CODE_START(__efi64_thunk)
        pushq   %rdi                    /* EFI runtime service address */
        lretq
 
-1:     movq    24(%rsp), %rsp
+1:     movq    0x20(%rsp), %rsp
        pop     %rbx
        pop     %rbp
        retq