Subject: port-mips/33166: pmap_remove_pv called for unmanaged pages
To: None <port-mips-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <gdamore@netbsd.org>
List: netbsd-bugs
Date: 03/29/2006 21:35:00
>Number: 33166
>Category: port-mips
>Synopsis: pmap_remove_pv called for unmanaged pages
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: port-mips-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Mar 29 21:35:00 +0000 2006
>Originator: Garrett D'Amore
>Release: 3.99.17
>Organization:
Tadpole Computer, Inc.
>Environment:
NetBSD cabernet 3.99.17 NetBSD 3.99.17 (METEOR) #10: Wed Mar 29 12:52:54 PST 2006 garrett@zippy:/home/garrett/netbsd/src/sys/arch/evbmips/compile/obj/METEOR evbmips
>Description:
when munmap() is called for a previously mmap()ed region of framebuffer memory located in high memory (> 4GB on Alchemy), pmap_remove tries to call pmap_remove_pv with a null "pg". This results in a panic.
>How-To-Repeat:
stick a pci device on PCI alchemy, and then mmap() some of it. when your process munmap()'s it (or exits), the system will panic.
>Fix:
Add appropriate checks for null pg. Here's a diff:
*** pmap.c.~1.166.~ Sat Dec 24 12:07:19 2005
--- pmap.c Wed Mar 29 12:52:07 2006
***************
*** 730,736 ****
pmap->pm_stats.wired_count--;
pmap->pm_stats.resident_count--;
pg = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(entry));
! pmap_remove_pv(pmap, sva, pg);
if (MIPS_HAS_R4K_MMU)
/* See above about G bit */
pte->pt_entry = MIPS3_PG_NV | MIPS3_PG_G;
--- 730,737 ----
pmap->pm_stats.wired_count--;
pmap->pm_stats.resident_count--;
pg = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(entry));
! if (pg)
! pmap_remove_pv(pmap, sva, pg);
if (MIPS_HAS_R4K_MMU)
/* See above about G bit */
pte->pt_entry = MIPS3_PG_NV | MIPS3_PG_G;
***************
*** 789,795 ****
pmap->pm_stats.wired_count--;
pmap->pm_stats.resident_count--;
pg = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(entry));
! pmap_remove_pv(pmap, sva, pg);
pte->pt_entry = mips_pg_nv_bit();
/*
* Flush the TLB for the given address.
--- 790,797 ----
pmap->pm_stats.wired_count--;
pmap->pm_stats.resident_count--;
pg = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(entry));
! if (pg)
! pmap_remove_pv(pmap, sva, pg);
pte->pt_entry = mips_pg_nv_bit();
/*
* Flush the TLB for the given address.