View | Details | Raw Unified | Return to bug 209821 | Differences between
and this patch

Collapse All | Expand All

(-)b/stand/efi/loader/arch/amd64/amd64_tramp.S (+53 lines)
Lines 58-64 amd64_tramp: Link Here
58
	ALIGN_TEXT
58
	ALIGN_TEXT
59
amd64_tramp_end:
59
amd64_tramp_end:
60
60
61
	.globl	amd64_tramp_inline
62
63
/*
64
 * void amd64_tramp_inline(uint64_t stack, uint64_t kernend,
65
 *			uint64_t modulep, uint64_t pagetable, uint64_t entry,
66
 *			uint64_t copy_dst, uint64_t copy_src, uint64_t copy_src_end)
67
 */
68
amd64_tramp_inline:
69
	cli			/* Make sure we don't get interrupted. */
70
71
	movq	%rsi,%r12	/* Stash the kernel values for later. */
72
	movq	%rdx,%r13
73
	movq	%rcx,%r14
74
	movq	%r8,%r15
75
76
	/* Copy the kernel from the staging area to the expected location
77
	 * in memory. The following code is equivalent to the efi_copy_finish
78
	 * function that amd64_tramp used to call. Inlining this code avoids
79
	 * a scenario when the system froze because efi_copy_finish
80
	 * overwrote its own code that just happened to be located somewhere
81
	 * in the destination range.
82
	 *
83
	 * while (copy_src < copy_src_end) *copy_dst++ = *copy_src++;
84
	 */
85
	movq	8(%rsp), %rax	/* rax = copy_src */
86
	movq	16(%rsp), %rcx	/* rcx = copy_src_end */
87
	cmpq	%rcx, %rax
88
	jnb	copy_done
89
	subq	%rax, %r9		/* r9 = copy_dst - copy_src */
90
loop:
91
	movq	(%rax), %rdx
92
	movq	%rdx, (%rax,%r9)
93
	addq	$8, %rax
94
	cmpq	%rax, %rcx
95
	ja	loop
96
copy_done:
97
98
	movq	%rdi,%rsp	/* Switch to our temporary stack. */
99
100
	pushq	%r12		/* Push kernend. */
101
	salq	$32,%r13	/* Shift modulep and push it. */
102
	pushq	%r13
103
	pushq	%r15		/* Push the entry address. */
104
	movq	%r14,%cr3	/* Switch page tables. */
105
	ret			/* "Return" to kernel entry. */
106
107
	ALIGN_TEXT
108
amd64_tramp_inline_end:
109
61
	.data
110
	.data
62
	.globl	amd64_tramp_size
111
	.globl	amd64_tramp_size
63
amd64_tramp_size:
112
amd64_tramp_size:
64
	.long	amd64_tramp_end-amd64_tramp
113
	.long	amd64_tramp_end-amd64_tramp
114
115
	.globl	amd64_tramp_inline_size
116
amd64_tramp_inline_size:
117
	.long	amd64_tramp_inline_end-amd64_tramp_inline
(-)b/stand/efi/loader/arch/amd64/elf64_freebsd.c (-7 / +11 lines)
Lines 78-88 static pml4_entry_t *PT4; Link Here
78
static pdp_entry_t *PT3;
78
static pdp_entry_t *PT3;
79
static pd_entry_t *PT2;
79
static pd_entry_t *PT2;
80
80
81
static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
81
static void (*trampoline)(uint64_t stack, uint64_t kernend,
82
    uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry);
82
    uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry,
83
    uint64_t copy_dst, uint64_t copy_src, uint64_t copy_src_end);
83
84
84
extern uintptr_t amd64_tramp;
85
extern uintptr_t amd64_tramp_inline;
85
extern uint32_t amd64_tramp_size;
86
extern uint32_t amd64_tramp_inline_size;
86
87
87
/*
88
/*
88
 * There is an ELF kernel and one or more ELF modules loaded.
89
 * There is an ELF kernel and one or more ELF modules loaded.
Lines 95-100 elf64_exec(struct preloaded_file *fp) Link Here
95
	struct file_metadata	*md;
96
	struct file_metadata	*md;
96
	Elf_Ehdr 		*ehdr;
97
	Elf_Ehdr 		*ehdr;
97
	vm_offset_t		modulep, kernend, trampcode, trampstack;
98
	vm_offset_t		modulep, kernend, trampcode, trampstack;
99
	uint64_t		copy_dst, copy_src, copy_src_end;
98
	int			err, i;
100
	int			err, i;
99
	ACPI_TABLE_RSDP		*rsdp;
101
	ACPI_TABLE_RSDP		*rsdp;
100
	char			buf[24];
102
	char			buf[24];
Lines 153-159 elf64_exec(struct preloaded_file *fp) Link Here
153
	    (EFI_PHYSICAL_ADDRESS *)&trampcode);
155
	    (EFI_PHYSICAL_ADDRESS *)&trampcode);
154
	bzero((void *)trampcode, EFI_PAGE_SIZE);
156
	bzero((void *)trampcode, EFI_PAGE_SIZE);
155
	trampstack = trampcode + EFI_PAGE_SIZE - 8;
157
	trampstack = trampcode + EFI_PAGE_SIZE - 8;
156
	bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size);
158
	bcopy((void *)&amd64_tramp_inline, (void *)trampcode, amd64_tramp_inline_size);
157
	trampoline = (void *)trampcode;
159
	trampoline = (void *)trampcode;
158
160
159
	PT4 = (pml4_entry_t *)0x0000000040000000;
161
	PT4 = (pml4_entry_t *)0x0000000040000000;
Lines 194-201 elf64_exec(struct preloaded_file *fp) Link Here
194
196
195
	dev_cleanup();
197
	dev_cleanup();
196
198
197
	trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4,
199
	efi_copy_get_locations(&copy_dst, &copy_src, &copy_src_end);
198
	    ehdr->e_entry);
200
201
	trampoline(trampstack, kernend, modulep, PT4,
202
	    ehdr->e_entry, copy_dst, copy_src, copy_src_end);
199
203
200
	panic("exec returned");
204
	panic("exec returned");
201
}
205
}
(-)b/stand/efi/loader/copy.c (+8 lines)
Lines 361-363 efi_copy_finish(void) Link Here
361
	while (src < last)
361
	while (src < last)
362
		*dst++ = *src++;
362
		*dst++ = *src++;
363
}
363
}
364
365
void
366
efi_copy_get_locations(uint64_t *dst, uint64_t *src, uint64_t *src_end)
367
{
368
	*src = (uint64_t)staging;
369
	*dst = (uint64_t)(staging - stage_offset);
370
	*src_end = (uint64_t)staging_end;
371
}
(-)b/stand/efi/loader/loader_efi.h (-1 / +1 lines)
Lines 44-48 ssize_t efi_readin(readin_handle_t fd, vm_offset_t dest, const size_t len); Link Here
44
void * efi_translate(vm_offset_t ptr);
44
void * efi_translate(vm_offset_t ptr);
45
45
46
void	efi_copy_finish(void);
46
void	efi_copy_finish(void);
47
void	efi_copy_get_locations(uint64_t *dst, uint64_t *src, uint64_t *src_end);
47
48
48
#endif	/* _LOADER_EFI_COPY_H_ */
49
#endif	/* _LOADER_EFI_COPY_H_ */
49
- 

Return to bug 209821