1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-25 11:37:56 +00:00

Fix a hideous TLB bug. pmap_unmapdev neglected to remove the device

mappings from the page tables, which were mapped with PG_G!  We could
reuse the page table entry for another mapping (pmap_mapdev) but it
would never have cleared any remaining PG_G TLB entries.
This commit is contained in:
Peter Wemm 2002-07-08 00:17:43 +00:00
parent dd5629cde7
commit 64ca701084
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=99561
2 changed files with 46 additions and 8 deletions
sys
amd64/amd64
i386/i386

View File

@ -3139,15 +3139,21 @@ pmap_mapdev(pa, size)
panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
pa = pa & PG_FRAME;
for (tmpva = va; size > 0;) {
for (tmpva = va; size > 0; ) {
pte = vtopte(tmpva);
*pte = pa | PG_RW | PG_V | pgeflag;
#ifdef SMP
cpu_invlpg((void *)tmpva);
#else
invltlb_1pg(tmpva);
#endif
size -= PAGE_SIZE;
tmpva += PAGE_SIZE;
pa += PAGE_SIZE;
}
invltlb();
#ifdef SMP
smp_invltlb();
#endif
return ((void *)(va + offset));
}
@ -3156,11 +3162,24 @@ pmap_unmapdev(va, size)
vm_offset_t va;
vm_size_t size;
{
vm_offset_t base, offset;
vm_offset_t base, offset, tmpva;
pt_entry_t *pte;
base = va & PG_FRAME;
offset = va & PAGE_MASK;
size = roundup(offset + size, PAGE_SIZE);
for (tmpva = base; tmpva < (base + size); tmpva += PAGE_SIZE) {
pte = vtopte(tmpva);
*pte = 0;
#ifdef SMP
cpu_invlpg((void *)tmpva);
#else
invltlb_1pg(tmpva);
#endif
}
#ifdef SMP
smp_invltlb();
#endif
kmem_free(kernel_map, base, size);
}

View File

@ -3139,15 +3139,21 @@ pmap_mapdev(pa, size)
panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
pa = pa & PG_FRAME;
for (tmpva = va; size > 0;) {
for (tmpva = va; size > 0; ) {
pte = vtopte(tmpva);
*pte = pa | PG_RW | PG_V | pgeflag;
#ifdef SMP
cpu_invlpg((void *)tmpva);
#else
invltlb_1pg(tmpva);
#endif
size -= PAGE_SIZE;
tmpva += PAGE_SIZE;
pa += PAGE_SIZE;
}
invltlb();
#ifdef SMP
smp_invltlb();
#endif
return ((void *)(va + offset));
}
@ -3156,11 +3162,24 @@ pmap_unmapdev(va, size)
vm_offset_t va;
vm_size_t size;
{
vm_offset_t base, offset;
vm_offset_t base, offset, tmpva;
pt_entry_t *pte;
base = va & PG_FRAME;
offset = va & PAGE_MASK;
size = roundup(offset + size, PAGE_SIZE);
for (tmpva = base; tmpva < (base + size); tmpva += PAGE_SIZE) {
pte = vtopte(tmpva);
*pte = 0;
#ifdef SMP
cpu_invlpg((void *)tmpva);
#else
invltlb_1pg(tmpva);
#endif
}
#ifdef SMP
smp_invltlb();
#endif
kmem_free(kernel_map, base, size);
}