diff --git a/stand/boot/efi/loader/arch/x86_64/amd64_tramp.S b/stand/boot/efi/loader/arch/x86_64/amd64_tramp.S
index fe84d56e767..02517255f14 100644
--- a/stand/boot/efi/loader/arch/x86_64/amd64_tramp.S
+++ b/stand/boot/efi/loader/arch/x86_64/amd64_tramp.S
@@ -1,9 +1,11 @@
 /*-
  * Copyright (c) 2013 The FreeBSD Foundation
+ * Copyright 2021 David Sebek <dasebek@gmail.com>
  * All rights reserved.
  *
  * This software was developed by Benno Rice under sponsorship from
  * the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -31,34 +33,53 @@
 #include <machine/asmacros.h>
 
 	.text
-	.globl	amd64_tramp
+	.globl	amd64_tramp_inline
 
 /*
- * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend,
- *		    uint64_t modulep, uint64_t pagetable, uint64_t entry)
+ * void amd64_tramp_inline(uint64_t stack %rdi, uint64_t kernend %rsi,
+ *    uint64_t modulep %rdx, uint64_t pagetable %rcx, uint64_t entry %r8,
+ *    uint64_t copy_dst %r9, uint64_t copy_src 8(%rsp),
+ *    uint64_t copy_src_end 16(%rsp))
  */
-amd64_tramp:
+amd64_tramp_inline:
 	cli			/* Make sure we don't get interrupted. */
-	movq	%rdi,%rsp	/* Switch to our temporary stack. */
 
-	movq	%rdx,%r12	/* Stash the kernel values for later. */
-	movq	%rcx,%r13
-	movq	%r8,%r14
-	movq	%r9,%r15
+	/*
+	 * Copy the kernel from the staging area to the expected location
+	 * in memory. The following code is equivalent to the efi_copy_finish
+	 * function that amd64_tramp used to call. Inlining this code avoids
+	 * a scenario when the system froze because efi_copy_finish
+	 * overwrote its own code that just happened to be located somewhere
+	 * in the destination range.
+	 *
+	 * while (copy_src < copy_src_end) *copy_dst++ = *copy_src++;
+	 */
+	movq	8(%rsp), %rax	/* rax = copy_src */
+	movq	16(%rsp), %r10	/* r10 = copy_src_end */
+	cmpq	%r10, %rax
+	jnb	copy_done
+	subq	%rax, %r9	/* r9 = copy_dst - copy_src */
+loop:
+	movq	(%rax), %r11
+	movq	%r11, (%rax,%r9)
+	addq	$8, %rax
+	cmpq	%rax, %r10
+	ja	loop
+copy_done:
 
-	callq	*%rsi		/* Call copy_finish so we're all ready to go. */
+	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. */
+	pushq	%rsi		/* Push kernend. */
+	salq	$32,%rdx	/* Shift modulep and push it. */
+	pushq	%rdx
+	pushq	%r8		/* Push the entry address. */
+	movq	%rcx,%cr3	/* Switch page tables. */
 	ret			/* "Return" to kernel entry. */
 
 	ALIGN_TEXT
-amd64_tramp_end:
+amd64_tramp_inline_end:
 
 	.data
-	.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/boot/efi/loader/arch/x86_64/elf64_freebsd.c b/stand/boot/efi/loader/arch/x86_64/elf64_freebsd.c
index a94062209fe..1a9d676edd7 100644
--- a/stand/boot/efi/loader/arch/x86_64/elf64_freebsd.c
+++ b/stand/boot/efi/loader/arch/x86_64/elf64_freebsd.c
@@ -73,12 +73,13 @@ static p4_entry_t *PT4;
 static p3_entry_t *PT3;
 static p2_entry_t *PT2;
 
-static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
+static void (*trampoline)(uint64_t stack, uint64_t kernend,
 			  uint64_t modulep, p4_entry_t *pagetable,
-			  uint64_t entry);
+			  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.
@@ -91,6 +92,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];
@@ -132,7 +134,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 = (p4_entry_t *)0x0000000040000000;
@@ -170,8 +172,10 @@ elf64_exec(struct preloaded_file *fp)
 
 	dev_cleanup();
 
-	trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4,
-	    ehdr->e_entry);
+	efi_copy_get_locations(&copy_dst, &copy_src, &copy_src_end);
+
+	trampoline(trampstack, kernend, modulep, PT4,
+	    ehdr->e_entry, copy_dst, copy_src, copy_src_end);
 
 	panic("exec returned");
 }
diff --git a/stand/boot/efi/loader/copy.c b/stand/boot/efi/loader/copy.c
index 3200018bda9..b4593e98e67 100644
--- a/stand/boot/efi/loader/copy.c
+++ b/stand/boot/efi/loader/copy.c
@@ -149,3 +149,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/boot/efi/loader/loader_efi.h b/stand/boot/efi/loader/loader_efi.h
index 364a5e55720..5586944593c 100644
--- a/stand/boot/efi/loader/loader_efi.h
+++ b/stand/boot/efi/loader/loader_efi.h
@@ -48,5 +48,6 @@ ssize_t	efi_readin(const int 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_ */
