From: Ard Biesheuvel <ardb@kernel.org>
To: linux-efi@vger.kernel.org
Cc: nivedita@alum.mit.edu, hdegoede@redhat.com,
Ard Biesheuvel <ardb@kernel.org>,
Andy Lutomirski <luto@kernel.org>, Ingo Molnar <mingo@redhat.com>
Subject: [PATCH 3/3] efi/x86: simplify mixed mode call wrapper
Date: Thu, 26 Dec 2019 16:14:07 +0100 [thread overview]
Message-ID: <20191226151407.29716-4-ardb@kernel.org> (raw)
In-Reply-To: <20191226151407.29716-1-ardb@kernel.org>
Calling 32-bit EFI runtime services from a 64-bit OS involves
switching back to the flat mapping with a stack carved out of
memory that is 32-bit addressable.
There is no need to actually execute the 64-bit part of this
routine from the flat mapping as well, as long as the entry
and return address fit in 32 bits. There is also no need to
preserve part of the calling context in global variables: we
can simply preserve the old stack pointer in %r11 across the
call into 32-bit firmware, and use either stack to preserve
other values.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/platform/efi/efi_thunk_64.S | 106 ++++++--------------
1 file changed, 29 insertions(+), 77 deletions(-)
diff --git a/arch/x86/platform/efi/efi_thunk_64.S b/arch/x86/platform/efi/efi_thunk_64.S
index 3189f1394701..7357808d3ae8 100644
--- a/arch/x86/platform/efi/efi_thunk_64.S
+++ b/arch/x86/platform/efi/efi_thunk_64.S
@@ -28,11 +28,17 @@
SYM_FUNC_START(efi64_thunk)
push %rbp
push %rbx
+ movl %ds, %ebx
+ push %rbx
+ movl %es, %ebx
+ push %rbx
+ movl %ss, %ebx
+ push %rbx
/*
* Switch to 1:1 mapped 32-bit stack pointer.
*/
- movq %rsp, efi_saved_sp(%rip)
+ movq %rsp, %r11
movq efi_scratch(%rip), %rsp
/*
@@ -41,87 +47,41 @@ SYM_FUNC_START(efi64_thunk)
movq $__START_KERNEL_map, %rax
subq phys_base(%rip), %rax
- /*
- * Push some physical addresses onto the stack. This is easier
- * to do now in a code64 section while the assembler can address
- * 64-bit values. Note that all the addresses on the stack are
- * 32-bit.
- */
- subq $16, %rsp
- leaq efi_exit32(%rip), %rbx
- subq %rax, %rbx
- movl %ebx, 8(%rsp)
-
- leaq __efi64_thunk(%rip), %rbx
- subq %rax, %rbx
- call *%rbx
-
- movq efi_saved_sp(%rip), %rsp
- pop %rbx
- pop %rbp
- retq
-SYM_FUNC_END(efi64_thunk)
-
-/*
- * We run this function from the 1:1 mapping.
- *
- * This function must be invoked with a 1:1 mapped stack.
- */
-SYM_FUNC_START_LOCAL(__efi64_thunk)
- movl %ds, %eax
- push %rax
- movl %es, %eax
- push %rax
- movl %ss, %eax
- push %rax
-
- subq $32, %rsp
+ subq $24, %rsp
movl %esi, 0x0(%rsp)
movl %edx, 0x4(%rsp)
movl %ecx, 0x8(%rsp)
- movq %r8, %rsi
- movl %esi, 0xc(%rsp)
- movq %r9, %rsi
- movl %esi, 0x10(%rsp)
-
+ movl %r8d, 0xc(%rsp)
+ movl %r9d, 0x10(%rsp)
leaq 1f(%rip), %rbx
- movq %rbx, func_rt_ptr(%rip)
+ subq %rax, %rbx
+ movl %ebx, 0x14(%rsp)
/* Switch to 32-bit descriptor */
pushq $__KERNEL32_CS
- leaq efi_enter32(%rip), %rax
- pushq %rax
+ leaq efi_enter32(%rip), %rbx
+ subq %rax, %rbx
+ pushq %rbx
lretq
-1: addq $32, %rsp
-
+ /*
+ * Convert 32-bit status code into 64-bit.
+ */
+1: btrl $31, %eax
+ jb 3f
+2: mov %r11, %rsp
pop %rbx
movl %ebx, %ss
pop %rbx
movl %ebx, %es
pop %rbx
movl %ebx, %ds
-
- /*
- * Convert 32-bit status code into 64-bit.
- */
- test %rax, %rax
- jz 1f
- movl %eax, %ecx
- andl $0x0fffffff, %ecx
- andl $0xf0000000, %eax
- shl $32, %rax
- or %rcx, %rax
-1:
- ret
-SYM_FUNC_END(__efi64_thunk)
-
-SYM_FUNC_START_LOCAL(efi_exit32)
- movq func_rt_ptr(%rip), %rax
- push %rax
- mov %rdi, %rax
- ret
-SYM_FUNC_END(efi_exit32)
+ pop %rbx
+ pop %rbp
+ retq
+3: btsq $63, %rax
+ jmp 2b
+SYM_FUNC_END(efi64_thunk)
.code32
/*
@@ -137,17 +97,9 @@ SYM_FUNC_START_LOCAL(efi_enter32)
call *%edi
- /* We must preserve return value */
- movl %eax, %edi
-
- movl 72(%esp), %eax
+ movl 20(%esp), %edi
pushl $__KERNEL_CS
- pushl %eax
+ pushl %edi
lret
SYM_FUNC_END(efi_enter32)
-
- .data
- .balign 8
-func_rt_ptr: .quad 0
-efi_saved_sp: .quad 0
--
2.17.1
next prev parent reply other threads:[~2019-12-26 15:16 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-26 15:14 [PATCH 0/3] efi/x86: clean up and simplify runtime call wrappers Ard Biesheuvel
2019-12-26 15:14 ` [PATCH 1/3] efi/x86: simplify 64-bit EFI firmware call wrapper Ard Biesheuvel
2019-12-27 2:42 ` Andy Lutomirski
2019-12-27 17:51 ` Arvind Sankar
2019-12-27 18:08 ` Arvind Sankar
2019-12-27 18:13 ` Ard Biesheuvel
2019-12-28 3:25 ` Andy Lutomirski
2019-12-28 4:43 ` Arvind Sankar
2019-12-28 5:29 ` Andy Lutomirski
2019-12-28 6:35 ` Arvind Sankar
2019-12-28 7:03 ` Andy Lutomirski
2019-12-28 8:51 ` Ard Biesheuvel
2019-12-28 9:00 ` Andy Lutomirski
2019-12-28 9:27 ` Ard Biesheuvel
2019-12-26 15:14 ` [PATCH 2/3] efi/x86: simplify i386 efi_call_phys() " Ard Biesheuvel
2019-12-26 15:14 ` Ard Biesheuvel [this message]
2019-12-27 2:56 ` [PATCH 3/3] efi/x86: simplify mixed mode " Andy Lutomirski
2019-12-27 8:04 ` Ard Biesheuvel
2019-12-27 4:34 ` Arvind Sankar
2019-12-27 8:05 ` Ard Biesheuvel
2019-12-27 12:52 ` Arvind Sankar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191226151407.29716-4-ardb@kernel.org \
--to=ardb@kernel.org \
--cc=hdegoede@redhat.com \
--cc=linux-efi@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=nivedita@alum.mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox