Page MenuHomeFreeBSD

D57462.diff
No OneTemporary

D57462.diff

diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c
--- a/stand/efi/loader/arch/amd64/elf64_freebsd.c
+++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c
@@ -89,7 +89,7 @@
Elf_Ehdr *ehdr;
vm_offset_t modulep, kernend, trampcode, trampstack;
int err, i;
- bool copy_auto;
+ bool copy_auto, needs_pt4;
copy_auto = copy_staging == COPY_STAGING_AUTO;
if (copy_auto)
@@ -156,6 +156,7 @@
PT2[i] = (pd_entry_t)i * M(2);
PT2[i] |= PG_V | PG_RW | PG_PS;
}
+ needs_pt4 = false;
} else {
PT4 = (pml4_entry_t *)G(4);
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9,
@@ -167,7 +168,35 @@
copy_staging = COPY_STAGING_AUTO;
return (ENOMEM);
}
+ needs_pt4 = true;
+ }
+
+ printf("%scopying staging tramp %p PT4 %p\n",
+ copy_staging == COPY_STAGING_ENABLE ? "" : "not ",
+ trampoline, PT4);
+ printf("Start @ 0x%lx ...\n", ehdr->e_entry);
+
+ /*
+ * we have to cleanup here because net_cleanup() doesn't work after
+ * we call ExitBootServices
+ */
+ dev_cleanup();
+ efi_time_fini();
+ err = bi_load(fp->f_args, &modulep, &kernend, true);
+ if (err != 0) {
+ efi_time_init();
+ if (copy_auto)
+ copy_staging = COPY_STAGING_AUTO;
+ return (err);
+ }
+
+ /*
+ * staging might move in bi_load because we automatiaclly move when we
+ * copy data in. At this point, staging can't move anymore, so create
+ * PT4 with the correct value.
+ */
+ if (needs_pt4) {
bzero(PT4, 9 * EFI_PAGE_SIZE);
PT3_l = &PT4[NPML4EPG * 1];
@@ -204,26 +233,6 @@
}
}
- printf("staging %#lx (%scopying) tramp %p PT4 %p\n",
- staging, copy_staging == COPY_STAGING_ENABLE ? "" : "not ",
- trampoline, PT4);
- printf("Start @ 0x%lx ...\n", ehdr->e_entry);
-
- /*
- * we have to cleanup here because net_cleanup() doesn't work after
- * we call ExitBootServices
- */
- dev_cleanup();
-
- efi_time_fini();
- err = bi_load(fp->f_args, &modulep, &kernend, true);
- if (err != 0) {
- efi_time_init();
- if (copy_auto)
- copy_staging = COPY_STAGING_AUTO;
- return (err);
- }
-
trampoline(trampstack, copy_staging == COPY_STAGING_ENABLE ?
efi_copy_finish : efi_copy_finish_nop, kernend, modulep,
PT4, ehdr->e_entry);
diff --git a/stand/efi/loader/arch/i386/elf64_freebsd.c b/stand/efi/loader/arch/i386/elf64_freebsd.c
--- a/stand/efi/loader/arch/i386/elf64_freebsd.c
+++ b/stand/efi/loader/arch/i386/elf64_freebsd.c
@@ -99,6 +99,7 @@
struct user_segment_descriptor *gdt;
vm_offset_t modulep, kernend, trampstack;
int i;
+ bool needs_pt4;
switch (copy_staging) {
case COPY_STAGING_ENABLE:
@@ -199,10 +200,8 @@
*/
PT2[i] = (i * M(2)) | PG_V | PG_RW | PG_PS;
}
+ needs_pt4 = false;
} else {
- pdpt_entry_t *PT3_l, *PT3_u;
- pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
-
err = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
EFI_SIZE_TO_PAGES(512 * 9 * sizeof(uint64_t)), &ptr);
if (EFI_ERROR(err)) {
@@ -213,6 +212,38 @@
}
PT4 = (pml4_entry_t *)(uintptr_t)ptr;
+ needs_pt4 = true;
+ }
+
+ printf("%scopying staging tramp %p PT4 %p GDT %p\n"
+ "Start @ %#llx ...\n",
+ type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, gdt,
+ ehdr->e_entry
+ );
+
+
+ /*
+ * we have to cleanup here because net_cleanup() doesn't work after
+ * we call ExitBootServices
+ */
+ dev_cleanup();
+
+ efi_time_fini();
+ err = bi_load(fp->f_args, &modulep, &kernend, true);
+ if (err != 0) {
+ efi_time_init();
+ return (err);
+ }
+
+ /*
+ * staging might move in bi_load because we automatiaclly move when we
+ * copy data in. At this point, staging can't move anymore, so create
+ * PT4 with the correct value.
+ */
+ if (needs_pt4) {
+ pdpt_entry_t *PT3_l, *PT3_u;
+ pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
+
PT3_l = &PT4[512];
PT3_u = &PT3_l[512];
PT2_l0 = &PT3_u[512];
@@ -245,27 +276,6 @@
}
}
- printf(
- "staging %#llx (%scopying) tramp %p PT4 %p GDT %p\n"
- "Start @ %#llx ...\n", staging,
- type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, gdt,
- ehdr->e_entry
- );
-
-
- /*
- * we have to cleanup here because net_cleanup() doesn't work after
- * we call ExitBootServices
- */
- dev_cleanup();
-
- efi_time_fini();
- err = bi_load(fp->f_args, &modulep, &kernend, true);
- if (err != 0) {
- efi_time_init();
- return (err);
- }
-
trampoline(trampstack, type == AllocateMaxAddress ? efi_copy_finish :
efi_copy_finish_nop, kernend, modulep, PT4, gdtr, ehdr->e_entry);
diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c
--- a/stand/efi/loader/bootinfo.c
+++ b/stand/efi/loader/bootinfo.c
@@ -209,6 +209,16 @@
}
#endif
+#if defined(__amd64__) || defined(__i386__)
+ /*
+ * Staging can't move after this point, so report the final value before
+ * we try to exit boot services below. The metadata added is added to
+ * the malloced arena that we setup when we started and doesn't interact
+ * with boot services.
+ */
+ printf("staging %#jx\n", (uintmax_t)staging);
+#endif
+
do_vmap = true;
efi_novmap = getenv("efi_disable_vmap");
if (efi_novmap != NULL)
@@ -298,14 +308,20 @@
* loader.conf(5). By default we will setup the virtual
* map entries.
*/
-
if (do_vmap)
efi_do_vmap(mm, sz, dsz, mmver);
+
+ /*
+ * Add the memory map to the metadata. addmetadata copies the data into
+ * the malloc arena, so we can safely free the memory map pages after.
+ * Or could if boot services was still running.
+ */
efihdr->memory_size = sz;
efihdr->descriptor_size = dsz;
efihdr->descriptor_version = mmver;
file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz,
efihdr);
+ /* BS->FreePages(addr, pages); */
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Jul 6, 6:25 AM (17 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34698791
Default Alt Text
D57462.diff (5 KB)

Event Timeline