From 0e5d2011ae8e9ddd78674abe7dfaa117863fcd84 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Thu, 29 Oct 2015 19:07:00 +0000 Subject: [PATCH] pmap_change_attr: Only fixup DMAP for DMAPed ranges pmap_change_attr must change the memory type of both the requested KVA and the corresponding DMAP mappings (if such mappings exist), to satisfy an Intel requirement that two or more mappings to the same physical pages must have the same memory type. However, not all kernel mapped pages have corresponding DMAP mappings -- for example, 64-bit BARs. Skip fixing up the DMAP for out-of-bounds addresses. Submitted by: Steve Wahl Reviewed by: alc, jhb Sponsored by: Dell Compellent Differential Revision: https://reviews.freebsd.org/D4030 --- sys/amd64/amd64/pmap.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 94a7d0c9640..883c1c5f4fe 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -6411,7 +6411,7 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) */ for (tmpva = base; tmpva < base + size; ) { pdpe = pmap_pdpe(kernel_pmap, tmpva); - if (*pdpe == 0) + if (pdpe == NULL || *pdpe == 0) return (EINVAL); if (*pdpe & PG_PS) { /* @@ -6484,7 +6484,8 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) X86_PG_PDE_CACHE); changed = TRUE; } - if (tmpva >= VM_MIN_KERNEL_ADDRESS) { + if (tmpva >= VM_MIN_KERNEL_ADDRESS && + (*pdpe & PG_PS_FRAME) < dmaplimit) { if (pa_start == pa_end) { /* Start physical address run. */ pa_start = *pdpe & PG_PS_FRAME; @@ -6513,7 +6514,8 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) X86_PG_PDE_CACHE); changed = TRUE; } - if (tmpva >= VM_MIN_KERNEL_ADDRESS) { + if (tmpva >= VM_MIN_KERNEL_ADDRESS && + (*pde & PG_PS_FRAME) < dmaplimit) { if (pa_start == pa_end) { /* Start physical address run. */ pa_start = *pde & PG_PS_FRAME; @@ -6540,7 +6542,8 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) X86_PG_PTE_CACHE); changed = TRUE; } - if (tmpva >= VM_MIN_KERNEL_ADDRESS) { + if (tmpva >= VM_MIN_KERNEL_ADDRESS && + (*pte & PG_PS_FRAME) < dmaplimit) { if (pa_start == pa_end) { /* Start physical address run. */ pa_start = *pte & PG_FRAME;