diff --git a/sys/amd64/amd64/efirt_machdep.c b/sys/amd64/amd64/efirt_machdep.c --- a/sys/amd64/amd64/efirt_machdep.c +++ b/sys/amd64/amd64/efirt_machdep.c @@ -60,6 +60,7 @@ #include #include #include +#include static pml5_entry_t *efi_pml5; static pml4_entry_t *efi_pml4; @@ -92,12 +93,12 @@ * indicate a failed mapping so that the caller may handle error. */ vm_offset_t -efi_phys_to_kva(vm_paddr_t paddr) +efi_phys_to_kva(vm_paddr_t paddr, vm_size_t size) { - if (paddr >= dmaplimit) - return (0); - return (PHYS_TO_DMAP(paddr)); + if (PHYS_SZ_IN_DMAP(paddr, size)) + return (PHYS_TO_DMAP(paddr)); + return (0); } static vm_page_t diff --git a/sys/arm64/arm64/efirt_machdep.c b/sys/arm64/arm64/efirt_machdep.c --- a/sys/arm64/arm64/efirt_machdep.c +++ b/sys/arm64/arm64/efirt_machdep.c @@ -60,6 +60,7 @@ #include #include #include +#include static vm_object_t obj_1t1_pt; static vm_pindex_t efi_1t1_idx; @@ -148,11 +149,11 @@ * indicate a failed mapping so that the caller may handle error. */ vm_offset_t -efi_phys_to_kva(vm_paddr_t paddr) +efi_phys_to_kva(vm_paddr_t paddr, vm_size_t size) { vm_offset_t vaddr; - if (PHYS_IN_DMAP(paddr)) { + if (PHYS_SZ_IN_DMAP(paddr, size)) { vaddr = PHYS_TO_DMAP(paddr); if (pmap_klookup(vaddr, NULL)) return (vaddr); diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c --- a/sys/dev/efidev/efirt.c +++ b/sys/dev/efidev/efirt.c @@ -185,7 +185,8 @@ return (0); } - efi_systbl = (struct efi_systbl *)efi_phys_to_kva(efi_systbl_phys); + efi_systbl = (struct efi_systbl *)efi_phys_to_kva(efi_systbl_phys, + sizeof(struct efi_systbl)); if (efi_systbl == NULL || efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { efi_systbl = NULL; if (bootverbose) @@ -239,7 +240,8 @@ * with an old loader.efi, check if the RS->GetTime function is within * the EFI map, and fail to attach if not. */ - rtdm = (struct efi_rt *)efi_phys_to_kva((uintptr_t)efi_runtime); + rtdm = (struct efi_rt *)efi_phys_to_kva((uintptr_t)efi_runtime, + sizeof(struct efi_rt)); if (rtdm == NULL || !efi_is_in_map(map, ndesc, efihdr->descriptor_size, (vm_offset_t)rtdm->rt_gettime)) { if (bootverbose) @@ -534,7 +536,7 @@ #define EFI_RT_METHOD_PA(method) \ ((uintptr_t)((struct efi_rt *)efi_phys_to_kva((uintptr_t) \ - efi_runtime))->method) + efi_runtime, sizeof(struct efi_rt)))->method) static int efi_get_time_locked(struct efi_tm *tm, struct efi_tmcap *tmcap) diff --git a/sys/sys/efi.h b/sys/sys/efi.h --- a/sys/sys/efi.h +++ b/sys/sys/efi.h @@ -236,7 +236,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); +vm_offset_t efi_phys_to_kva(vm_paddr_t, vm_size_t); int efi_rt_arch_call(struct efirt_callinfo *); bool efi_create_1t1_map(struct efi_md *, int, int); void efi_destroy_1t1_map(void); diff --git a/sys/vm/vm_param.h b/sys/vm/vm_param.h --- a/sys/vm/vm_param.h +++ b/sys/vm/vm_param.h @@ -133,6 +133,12 @@ #endif #define PHYS_AVAIL_COUNT (PHYS_AVAIL_ENTRIES + 2) +/* + * Check that a physical address range completely lies within the direct map. + */ +#define PHYS_SZ_IN_DMAP(pa, sz) \ + (PHYS_IN_DMAP((pa)) && PHYS_IN_DMAP((pa) + (sz) - 1)) + #ifndef ASSEMBLER #ifdef _KERNEL #define num_pages(x) \