Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Oct 2015 16:42:20 +0000
From:      Steven Wahl <Steve_Wahl@Dell.com>
To:        "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>
Cc:        "kib@freebsd.org" <kib@freebsd.org>, "cem@freebsd.org" <cem@freebsd.org>,  "jhb@freebsd.org" <jhb@freebsd.org>, Eric Van Gyzen <Eric.VanGyzen@compellent.com>
Subject:   re: svn commit: r290130 - head/sys/dev/ntb/ntb_hw 
Message-ID:  <bbf3208d2a4d40998c2154402208c016@mspexmb1.Beer.Town>

next in thread | raw e-mail | index | archive | help
We ran into this exact problem, pmap_change_attr not working right with lar=
ge bars.  I had been working up to seeing if this compiles on the current h=
ead, introducing myself to the community, seeing if this would be accepted.=
=0A=
=0A=
But looks like it's needed sooner, so in case it might save you some time, =
here's the patch we developed for this problem.=0A=
=0A=
--> Steve Wahl, Dell Compellent, Eden Prairie, MN=0A=
=0A=
=0A=
commit 7d112aa8767390cb9dd020325a9f23aaac7fe5a0=0A=
Author: swahl <steve_wahl@dell.com>=0A=
Date:   Thu Oct 1 14:36:48 2015 -0500=0A=
=0A=
    CQ00492954: FreeBSD traps on call to pmap_change_attr() with large PLX =
BAR=0A=
    =0A=
    If an address passed to pmap_change_attr() refers to a virtual address,=
=0A=
    the function must also change the direct mapping of this same=0A=
    region (if any) to match, or intel says the result is undefined.=0A=
    =0A=
    But the original code did not check if the virtual address actually fel=
l=0A=
    within the direct mapped region before attempting to make this change.=
=0A=
    The attempt to look up the direct mapped page entries returned NULL, an=
d=0A=
    this was dereferenced causing a panic.=0A=
    =0A=
    This is fixed by checking whether the address is outside of the direct=
=0A=
    mapped range before trying to change the direct mapped entries.=0A=
=0A=
diff --git a/src/sys/amd64/amd64/pmap.c b/src/sys/amd64/amd64/pmap.c=0A=
index fe09ace..dee22de 100644=0A=
--- a/src/sys/amd64/amd64/pmap.c=0A=
+++ b/src/sys/amd64/amd64/pmap.c=0A=
@@ -6268,7 +6268,7 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t siz=
e, int mode)=0A=
 	 */=0A=
 	for (tmpva =3D base; tmpva < base + size; ) {=0A=
 		pdpe =3D pmap_pdpe(kernel_pmap, tmpva);=0A=
-		if (*pdpe =3D=3D 0)=0A=
+		if (pdpe =3D=3D NULL || *pdpe =3D=3D 0)=0A=
 			return (EINVAL);=0A=
 		if (*pdpe & PG_PS) {=0A=
 			/*=0A=
@@ -6341,7 +6341,8 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t siz=
e, int mode)=0A=
 				    X86_PG_PDE_CACHE);=0A=
 				changed =3D TRUE;=0A=
 			}=0A=
-			if (tmpva >=3D VM_MIN_KERNEL_ADDRESS) {=0A=
+			if (tmpva >=3D VM_MIN_KERNEL_ADDRESS &&=0A=
+			    (*pdpe & PG_PS_FRAME) < dmaplimit) {=0A=
 				if (pa_start =3D=3D pa_end) {=0A=
 					/* Start physical address run. */=0A=
 					pa_start =3D *pdpe & PG_PS_FRAME;=0A=
@@ -6370,7 +6371,8 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t siz=
e, int mode)=0A=
 				    X86_PG_PDE_CACHE);=0A=
 				changed =3D TRUE;=0A=
 			}=0A=
-			if (tmpva >=3D VM_MIN_KERNEL_ADDRESS) {=0A=
+			if (tmpva >=3D VM_MIN_KERNEL_ADDRESS &&=0A=
+			    (*pde & PG_PS_FRAME) < dmaplimit) {=0A=
 				if (pa_start =3D=3D pa_end) {=0A=
 					/* Start physical address run. */=0A=
 					pa_start =3D *pde & PG_PS_FRAME;=0A=
@@ -6397,7 +6399,8 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t siz=
e, int mode)=0A=
 				    X86_PG_PTE_CACHE);=0A=
 				changed =3D TRUE;=0A=
 			}=0A=
-			if (tmpva >=3D VM_MIN_KERNEL_ADDRESS) {=0A=
+			if (tmpva >=3D VM_MIN_KERNEL_ADDRESS &&=0A=
+			    (*pte & PG_FRAME) < dmaplimit) {=0A=
 				if (pa_start =3D=3D pa_end) {=0A=
 					/* Start physical address run. */=0A=
 					pa_start =3D *pte & PG_FRAME;=0A=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bbf3208d2a4d40998c2154402208c016>