Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159433360
D57462.id179291.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D57462.id179291.diff
View Options
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/bootinfo.c b/stand/efi/loader/bootinfo.c
--- a/stand/efi/loader/bootinfo.c
+++ b/stand/efi/loader/bootinfo.c
@@ -208,6 +208,13 @@
file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb);
}
#endif
+ /*
+ * 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 %#lx\n", staging);
do_vmap = true;
efi_novmap = getenv("efi_disable_vmap");
@@ -298,14 +305,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
Details
Attached
Mime Type
text/plain
Expires
Mon, Jun 15, 1:01 AM (6 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33961910
Default Alt Text
D57462.id179291.diff (3 KB)
Attached To
Mode
D57462: loader.efi: Fix when staging moves late
Attached
Detach File
Event Timeline
Log In to Comment