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>