Index: sys/amd64/amd64/efirt_machdep.c =================================================================== --- sys/amd64/amd64/efirt_machdep.c +++ sys/amd64/amd64/efirt_machdep.c @@ -84,6 +84,19 @@ efi_pml4_page = NULL; } +/* + * Map a physical address from EFI runtime space into KVA space. Returns 0 to + * indicate a failed mapping so that the caller may handle error. + */ +vm_offset_t +efi_phys_to_kva(vm_paddr_t paddr) +{ + + if (paddr >= dmaplimit) + return (0); + return (PHYS_TO_DMAP(paddr)); +} + static vm_page_t efi_1t1_page(void) { Index: sys/arm64/arm64/efirt_machdep.c =================================================================== --- sys/arm64/arm64/efirt_machdep.c +++ sys/arm64/arm64/efirt_machdep.c @@ -142,6 +142,19 @@ return (l3); } +/* + * Map a physical address from EFI runtime space into KVA space. Returns 0 to + * indicate a failed mapping so that the caller may handle error. + */ +vm_offset_t +efi_phys_to_kva(vm_paddr_t paddr) +{ + + if (!PHYS_IN_DMAP(paddr)) + return (0); + return (PHYS_TO_DMAP(paddr)); +} + /* * Create the 1:1 virtual to physical map for EFI */ Index: sys/dev/efidev/efirt.c =================================================================== --- sys/dev/efidev/efirt.c +++ sys/dev/efidev/efirt.c @@ -131,9 +131,10 @@ { struct efi_map_header *efihdr; struct efi_md *map; + struct efi_rt *rtdm; caddr_t kmdp; size_t efisz; - int rt_disabled; + int ndesc, rt_disabled; rt_disabled = 0; TUNABLE_INT_FETCH("efi.rt.disabled", &rt_disabled); @@ -146,13 +147,9 @@ printf("EFI systbl not available\n"); return (0); } - if (!PMAP_HAS_DMAP) { - if (bootverbose) - printf("EFI systbl requires direct map\n"); - return (0); - } - efi_systbl = (struct efi_systbl *)PHYS_TO_DMAP(efi_systbl_phys); - if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { + + efi_systbl = (struct efi_systbl *)efi_phys_to_kva(efi_systbl_phys); + if (efi_systbl == NULL || efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { efi_systbl = NULL; if (bootverbose) printf("EFI systbl signature invalid\n"); @@ -180,8 +177,8 @@ if (efihdr->descriptor_size == 0) return (ENOMEM); - if (!efi_create_1t1_map(map, efihdr->memory_size / - efihdr->descriptor_size, efihdr->descriptor_size)) { + ndesc = efihdr->memory_size / efihdr->descriptor_size; + if (!efi_create_1t1_map(map, ndesc, efihdr->descriptor_size)) { if (bootverbose) printf("EFI cannot create runtime map\n"); return (ENOMEM); @@ -196,6 +193,7 @@ return (ENXIO); } +#if defined(__aarch64__) || defined(__amd64__) /* * Some UEFI implementations have multiple implementations of the * RS->GetTime function. They switch from one we can only use early @@ -203,14 +201,10 @@ * call RS->SetVirtualAddressMap. As this is not always the case, e.g. * with an old loader.efi, check if the RS->GetTime function is within * the EFI map, and fail to attach if not. - * - * We need to enter into the EFI environment as efi_runtime may point - * to an EFI address. */ - efi_enter(); - if (!efi_is_in_map(map, efihdr->memory_size / efihdr->descriptor_size, - efihdr->descriptor_size, (vm_offset_t)efi_runtime->rt_gettime)) { - efi_leave(); + rtdm = (struct efi_rt *)efi_phys_to_kva((uintptr_t)efi_runtime); + if (rtdm == NULL || !efi_is_in_map(map, ndesc, efihdr->descriptor_size, + (vm_offset_t)rtdm->rt_gettime)) { if (bootverbose) printf( "EFI runtime services table has an invalid pointer\n"); @@ -218,7 +212,7 @@ efi_destroy_1t1_map(); return (ENXIO); } - efi_leave(); +#endif return (0); } @@ -291,7 +285,7 @@ ct = efi_cfgtbl; while (count--) { if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) { - *ptr = (void *)PHYS_TO_DMAP(ct->ct_data); + *ptr = efi_phys_to_kva(ct->ct_data); return (0); } ct++; Index: sys/sys/efi.h =================================================================== --- sys/sys/efi.h +++ sys/sys/efi.h @@ -172,6 +172,7 @@ /* Internal MD EFI functions */ int efi_arch_enter(void); void efi_arch_leave(void); +vm_offset_t efi_phys_to_kva(vm_paddr_t); bool efi_create_1t1_map(struct efi_md *, int, int); void efi_destroy_1t1_map(void);