The branch main has been updated by vexeduxr: URL: https://cgit.FreeBSD.org/src/commit/?id=85dcdb7aad85498b3f497b8752e69b8612b27cb7
commit 85dcdb7aad85498b3f497b8752e69b8612b27cb7 Author: Ahmad Khalifa <vexed...@freebsd.org> AuthorDate: 2025-07-06 19:10:25 +0000 Commit: Ahmad Khalifa <vexed...@freebsd.org> CommitDate: 2025-07-06 19:26:07 +0000 amd64: allow the mapping of other regions for efirt Some BIOSes access data outside of regions marked as "runtime" in their runtime EFI functions. Allow the mapping and preservation of other regions through a tunable. The tunable is a bitmap specifying the regions to map. e.g bit 3 would be set to map BootServicesCode. Currently allowed regions are: BootServicesCode BootServicesData RuntimeServicesCode RuntimeServicesData ACPIMemoryNVS PR: 287422 Reviewed by: kib Approved by: imp (mentor) Differential Revision: https://reviews.freebsd.org/D51146 --- sys/amd64/amd64/efirt_machdep.c | 18 +++++++++++++++++- sys/amd64/amd64/machdep.c | 8 ++++++-- sys/amd64/include/efi.h | 4 ++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/sys/amd64/amd64/efirt_machdep.c b/sys/amd64/amd64/efirt_machdep.c index 81a28ebe97ee..75c357f6e3df 100644 --- a/sys/amd64/amd64/efirt_machdep.c +++ b/sys/amd64/amd64/efirt_machdep.c @@ -56,6 +56,15 @@ #include <vm/vm_pager.h> #include <vm/vm_radix.h> +/* The EFI regions we're allowed to map. */ +#define EFI_ALLOWED_TYPES_MASK ( \ + 1u << EFI_MD_TYPE_BS_CODE | 1u << EFI_MD_TYPE_BS_DATA | \ + 1u << EFI_MD_TYPE_RT_CODE | 1u << EFI_MD_TYPE_RT_DATA | \ + 1u << EFI_MD_TYPE_FIRMWARE \ +) + +uint32_t efi_map_regs; + static pml5_entry_t *efi_pml5; static pml4_entry_t *efi_pml4; static vm_object_t obj_1t1_pt; @@ -198,9 +207,16 @@ efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz) pmap_pinit_pml4(efi_pmltop_page); } + if ((efi_map_regs & ~EFI_ALLOWED_TYPES_MASK) != 0) { + printf("Ignoring the following runtime EFI regions: %#x\n", + efi_map_regs & ~EFI_ALLOWED_TYPES_MASK); + efi_map_regs &= EFI_ALLOWED_TYPES_MASK; + } + for (i = 0, p = map; i < ndesc; i++, p = efi_next_descriptor(p, descsz)) { - if ((p->md_attr & EFI_MD_ATTR_RT) == 0) + if ((p->md_attr & EFI_MD_ATTR_RT) == 0 && + !EFI_MAP_BOOTTYPE_ALLOWED(p->md_type)) continue; if (p->md_virt != 0 && p->md_virt != p->md_phys) { if (bootverbose) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 9724a6acb130..1e8f9b22bd19 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -758,6 +758,7 @@ add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap, printf("%23s %12s %12s %8s %4s\n", "Type", "Physical", "Virtual", "#Pages", "Attr"); + TUNABLE_INT_FETCH("machdep.efirt.regs", &efi_map_regs); for (i = 0, p = map; i < ndesc; i++, p = efi_next_descriptor(p, efihdr->descriptor_size)) { if (boothowto & RB_VERBOSE) { @@ -795,10 +796,13 @@ add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap, } switch (p->md_type) { - case EFI_MD_TYPE_CODE: - case EFI_MD_TYPE_DATA: case EFI_MD_TYPE_BS_CODE: case EFI_MD_TYPE_BS_DATA: + if (EFI_MAP_BOOTTYPE_ALLOWED(p->md_type)) + continue; + /* FALLTHROUGH */ + case EFI_MD_TYPE_CODE: + case EFI_MD_TYPE_DATA: case EFI_MD_TYPE_FREE: /* * We're allowed to use any entry with these types. diff --git a/sys/amd64/include/efi.h b/sys/amd64/include/efi.h index b47c4aa27ac7..439f2f0b317d 100644 --- a/sys/amd64/include/efi.h +++ b/sys/amd64/include/efi.h @@ -53,6 +53,10 @@ #define EFI_TIME_OWNED() mtx_assert(&atrtc_time_lock, MA_OWNED) #define EFI_RT_HANDLE_FAULTS_DEFAULT 1 + +#define EFI_MAP_BOOTTYPE_ALLOWED(type) (((efi_map_regs >> (type)) & 1) != 0) + +extern uint32_t efi_map_regs; #endif struct efirt_callinfo {