FreeBSD Bugzilla – Attachment 225333 Details for
Bug 209821
UEFI - installation media hangs when booting on ASUS P6P67 DELUXE
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Fix a boot hang on some systems
0001-efi-loader-amd64-Fix-a-boot-crash-or-hang-on-some-sy.patch (text/plain), 5.79 KB, created by
David Sebek
on 2021-05-28 15:50:48 UTC
(
hide
)
Description:
Fix a boot hang on some systems
Filename:
MIME Type:
Creator:
David Sebek
Created:
2021-05-28 15:50:48 UTC
Size:
5.79 KB
patch
obsolete
>From 3c7acdd7ec2c526534a34442d4a0f533e6a3b62f Mon Sep 17 00:00:00 2001 >From: David Sebek <dasebek@gmail.com> >Date: Fri, 28 May 2021 10:58:36 -0400 >Subject: [PATCH] efi: loader: amd64: Fix a boot crash or hang on some systems > >Instead of calling the efi_copy_finish function from amd64_tramp, >include the copy instructions in the trampoline code itself. >This avoids boot hangs and restarts in the cases when >the EFI loader code and/or data segments happen to be located >at a memory loacation that is overwritten during the copy process. > >Signed-off-by: David Sebek <dasebek@gmail.com> >--- > stand/efi/loader/arch/amd64/amd64_tramp.S | 53 +++++++++++++++++++++ > stand/efi/loader/arch/amd64/elf64_freebsd.c | 18 ++++--- > stand/efi/loader/copy.c | 8 ++++ > stand/efi/loader/loader_efi.h | 1 + > 4 files changed, 73 insertions(+), 7 deletions(-) > >diff --git a/stand/efi/loader/arch/amd64/amd64_tramp.S b/stand/efi/loader/arch/amd64/amd64_tramp.S >index 877705407f9..88707ba7312 100644 >--- a/stand/efi/loader/arch/amd64/amd64_tramp.S >+++ b/stand/efi/loader/arch/amd64/amd64_tramp.S >@@ -61,6 +61,55 @@ amd64_tramp: > ALIGN_TEXT > amd64_tramp_end: > >+/* >+ * void amd64_tramp_inline(uint64_t stack, uint64_t kernend, >+ * uint64_t modulep, uint64_t pagetable, uint64_t entry, >+ * uint64_t copy_dst, uint64_t copy_src, uint64_t copy_src_end) >+ */ >+ .globl amd64_tramp_inline >+amd64_tramp_inline: >+ cli /* Make sure we don't get interrupted. */ >+ >+ movq %rsi,%r12 /* Stash the kernel values for later. */ >+ movq %rdx,%r13 >+ movq %rcx,%r14 >+ movq %r8,%r15 >+ >+ /* Copy the content of the staging area to the expected location. >+ * A code similar to efi_copy_finish from copy.c is inlined here >+ * instead of calling a copy_finish function like amd64_tramp did. >+ * In some cases, the UEFI bootloader may be loaded to a memory location >+ * that happens to be overwritten during this copy process. In such a case, >+ * calling copy_finish could result in a system reboot or a bootloader to >+ * hang. >+ * >+ * while (copy_src < copy_src_end) *copy_dst++ = *copy_src++; >+ */ >+ movq 8(%rsp), %rax /* rax = copy_src */ >+ movq 16(%rsp), %rcx /* rcx = copy_src_end */ >+ cmpq %rcx, %rax >+ jnb copy_done >+ subq %rax, %r9 /* r9 = copy_dst - copy_src */ >+loop: >+ movq (%rax), %rdx >+ movq %rdx, (%rax,%r9) >+ addq $8, %rax >+ cmpq %rax, %rcx >+ ja loop >+copy_done: >+ >+ movq %rdi,%rsp /* Switch to our temporary stack. */ >+ >+ pushq %r12 /* Push kernend. */ >+ salq $32,%r13 /* Shift modulep and push it. */ >+ pushq %r13 >+ pushq %r15 /* Push the entry address. */ >+ movq %r14,%cr3 /* Switch page tables. */ >+ ret /* "Return" to kernel entry. */ >+ >+ ALIGN_TEXT >+amd64_tramp_inline_end: >+ > /* void multiboot2_exec(uint64_t entry, uint64_t multiboot_info, uint64_t stack) */ > .globl multiboot2_exec > multiboot2_exec: >@@ -74,3 +123,7 @@ multiboot2_exec: > .globl amd64_tramp_size > amd64_tramp_size: > .long amd64_tramp_end-amd64_tramp >+ >+ .globl amd64_tramp_inline_size >+amd64_tramp_inline_size: >+ .long amd64_tramp_inline_end-amd64_tramp_inline >diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c >index a950ca55e84..852199a43f5 100644 >--- a/stand/efi/loader/arch/amd64/elf64_freebsd.c >+++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c >@@ -84,11 +84,12 @@ static pml4_entry_t *PT4; > static pdp_entry_t *PT3; > static pd_entry_t *PT2; > >-static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, >- uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry); >+static void (*trampoline)(uint64_t stack, uint64_t kernend, >+ uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry, >+ uint64_t copy_dst, uint64_t copy_src, uint64_t copy_src_end); > >-extern uintptr_t amd64_tramp; >-extern uint32_t amd64_tramp_size; >+extern uintptr_t amd64_tramp_inline; >+extern uint32_t amd64_tramp_inline_size; > > /* > * There is an ELF kernel and one or more ELF modules loaded. >@@ -101,6 +102,7 @@ elf64_exec(struct preloaded_file *fp) > struct file_metadata *md; > Elf_Ehdr *ehdr; > vm_offset_t modulep, kernend, trampcode, trampstack; >+ uint64_t copy_dst, copy_src, copy_src_end; > int err, i; > ACPI_TABLE_RSDP *rsdp; > char buf[24]; >@@ -159,7 +161,7 @@ elf64_exec(struct preloaded_file *fp) > (EFI_PHYSICAL_ADDRESS *)&trampcode); > bzero((void *)trampcode, EFI_PAGE_SIZE); > trampstack = trampcode + EFI_PAGE_SIZE - 8; >- bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size); >+ bcopy((void *)&amd64_tramp_inline, (void *)trampcode, amd64_tramp_inline_size); > trampoline = (void *)trampcode; > > PT4 = (pml4_entry_t *)0x0000000040000000; >@@ -200,8 +202,10 @@ elf64_exec(struct preloaded_file *fp) > > dev_cleanup(); > >- trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4, >- ehdr->e_entry); >+ efi_copy_get_locations(©_dst, ©_src, ©_src_end); >+ >+ trampoline(trampstack, kernend, modulep, PT4, >+ ehdr->e_entry, copy_dst, copy_src, copy_src_end); > > panic("exec returned"); > } >diff --git a/stand/efi/loader/copy.c b/stand/efi/loader/copy.c >index e723b61e3bc..f063b6615bc 100644 >--- a/stand/efi/loader/copy.c >+++ b/stand/efi/loader/copy.c >@@ -364,3 +364,11 @@ efi_copy_finish(void) > while (src < last) > *dst++ = *src++; > } >+ >+void >+efi_copy_get_locations(uint64_t * dst, uint64_t * src, uint64_t * src_end) >+{ >+ *src = (uint64_t)staging; >+ *dst = (uint64_t)(staging - stage_offset); >+ *src_end = (uint64_t)staging_end; >+} >diff --git a/stand/efi/loader/loader_efi.h b/stand/efi/loader/loader_efi.h >index 4d077514e42..f3a052a63cf 100644 >--- a/stand/efi/loader/loader_efi.h >+++ b/stand/efi/loader/loader_efi.h >@@ -44,5 +44,6 @@ ssize_t efi_readin(readin_handle_t fd, vm_offset_t dest, const size_t len); > void * efi_translate(vm_offset_t ptr); > > void efi_copy_finish(void); >+void efi_copy_get_locations(uint64_t *dst, uint64_t *src, uint64_t *src_end); > > #endif /* _LOADER_EFI_COPY_H_ */ >-- >2.31.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 209821
:
225333
|
225480
|
230798
|
230812
|
230823