linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86/efi: Restore Firmware IDT in before ExitBootServices()
@ 2021-08-20  7:34 Joerg Roedel
  2021-08-20  7:41 ` Ard Biesheuvel
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Joerg Roedel @ 2021-08-20  7:34 UTC (permalink / raw)
  To: x86
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, hpa, Joerg Roedel,
	Kees Cook, Andy Lutomirski, Uros Bizjak, Arvind Sankar,
	Ard Biesheuvel, linux-kernel, Fabio Aiuto, stable

From: Joerg Roedel <jroedel@suse.de>

Commit 79419e13e808 ("x86/boot/compressed/64: Setup IDT in startup_32
boot path") introduced an IDT into the 32 bit boot path of the
decompressor stub.  But the IDT is set up before ExitBootServices() is
called and some UEFI firmwares rely on their own IDT.

Save the firmware IDT on boot and restore it before calling into EFI
functions to fix boot failures introduced by above commit.

Reported-by: Fabio Aiuto <fabioaiuto83@gmail.com>
Fixes: 79419e13e808 ("x86/boot/compressed/64: Setup IDT in startup_32 boot path")
Cc: stable@vger.kernel.org # 5.13+
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 arch/x86/boot/compressed/efi_thunk_64.S | 23 ++++++++++++++++++-----
 arch/x86/boot/compressed/head_64.S      |  3 +++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/x86/boot/compressed/efi_thunk_64.S b/arch/x86/boot/compressed/efi_thunk_64.S
index 95a223b3e56a..99cfd5dea23c 100644
--- a/arch/x86/boot/compressed/efi_thunk_64.S
+++ b/arch/x86/boot/compressed/efi_thunk_64.S
@@ -39,7 +39,7 @@ SYM_FUNC_START(__efi64_thunk)
 	/*
 	 * Convert x86-64 ABI params to i386 ABI
 	 */
-	subq	$32, %rsp
+	subq	$64, %rsp
 	movl	%esi, 0x0(%rsp)
 	movl	%edx, 0x4(%rsp)
 	movl	%ecx, 0x8(%rsp)
@@ -49,14 +49,19 @@ SYM_FUNC_START(__efi64_thunk)
 	leaq	0x14(%rsp), %rbx
 	sgdt	(%rbx)
 
+	addq	$16, %rbx
+	sidt	(%rbx)
+
 	/*
-	 * Switch to gdt with 32-bit segments. This is the firmware GDT
-	 * that was installed when the kernel started executing. This
-	 * pointer was saved at the EFI stub entry point in head_64.S.
+	 * 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
+	 * pointers were saved at the EFI stub entry point in head_64.S.
 	 *
 	 * Pass the saved DS selector to the 32-bit code, and use far return to
 	 * restore the saved CS selector.
 	 */
+	leaq	efi32_boot_idt(%rip), %rax
+	lidt	(%rax)
 	leaq	efi32_boot_gdt(%rip), %rax
 	lgdt	(%rax)
 
@@ -67,7 +72,7 @@ SYM_FUNC_START(__efi64_thunk)
 	pushq	%rax
 	lretq
 
-1:	addq	$32, %rsp
+1:	addq	$64, %rsp
 	movq	%rdi, %rax
 
 	pop	%rbx
@@ -132,6 +137,9 @@ SYM_FUNC_START_LOCAL(efi_enter32)
 	 */
 	cli
 
+	lidtl	(%ebx)
+	subl	$16, %ebx
+
 	lgdtl	(%ebx)
 
 	movl	%cr4, %eax
@@ -166,6 +174,11 @@ SYM_DATA_START(efi32_boot_gdt)
 	.quad	0
 SYM_DATA_END(efi32_boot_gdt)
 
+SYM_DATA_START(efi32_boot_idt)
+	.word	0
+	.quad	0
+SYM_DATA_END(efi32_boot_idt)
+
 SYM_DATA_START(efi32_boot_cs)
 	.word	0
 SYM_DATA_END(efi32_boot_cs)
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index a2347ded77ea..572c535cf45b 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -319,6 +319,9 @@ SYM_INNER_LABEL(efi32_pe_stub_entry, SYM_L_LOCAL)
 	movw	%cs, rva(efi32_boot_cs)(%ebp)
 	movw	%ds, rva(efi32_boot_ds)(%ebp)
 
+	/* Store firmware IDT descriptor */
+	sidtl	rva(efi32_boot_idt)(%ebp)
+
 	/* Disable paging */
 	movl	%cr0, %eax
 	btrl	$X86_CR0_PG_BIT, %eax
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-08-20 16:11 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-20  7:34 [PATCH] x86/efi: Restore Firmware IDT in before ExitBootServices() Joerg Roedel
2021-08-20  7:41 ` Ard Biesheuvel
2021-08-20  8:01   ` Joerg Roedel
2021-08-20  8:43 ` David Laight
2021-08-20  8:52   ` 'Joerg Roedel'
2021-08-20  9:02     ` David Laight
2021-08-20 10:19       ` 'Joerg Roedel'
2021-08-20 11:31         ` Ard Biesheuvel
2021-08-20 11:51           ` Joerg Roedel
2021-08-20 15:46           ` David Laight
2021-08-20 16:04             ` Joerg Roedel
2021-08-20  9:26 ` Borislav Petkov
2021-08-20 11:24   ` Borislav Petkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).