Subject: port-hppa/20933: hppa vmapbuf()/vunmapbuf() bugs
To: None <gnats-bugs@gnats.netbsd.org>
From: None <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 03/30/2003 00:18:25
>Number: 20933
>Category: port-hppa
>Synopsis: hppa vmapbuf()/vunmapbuf() bugs
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-hppa-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Mar 29 07:19:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator: Izumi Tsutsui
>Release: NetBSD 1.6K around 20021230, but -current has the same code
>Organization:
>Environment:
System: NetBSD 1.6K
Architecture: hppa
Machine: hp700 712/60 and 735/125
>Description:
Current vmapbuf()/vunmapbuf() in hppa/vm_machdep.c have bugs
which cause "DTLB miss trap" panics on physio access:
- In vmapbuf(), uvm_map(9) is called with wrong addr (uoffset) and size values.
(size is rounded up, but addr isn't truncated)
- In vunmapbuf(), pmap_remove() is not called.
>How-To-Repeat:
Code inspection.
>Fix:
The following patch fixes the problems,
but It's better to sync with other ports.
Index: vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hppa/hppa/vm_machdep.c,v
retrieving revision 1.2
diff -u -r1.2 vm_machdep.c
--- vm_machdep.c 2002/07/01 16:10:03 1.2
+++ vm_machdep.c 2003/03/29 14:53:31
@@ -290,9 +290,9 @@
p = bp->b_proc;
map = &p->p_vmspace->vm_map;
bp->b_saveaddr = bp->b_data;
- addr = (vaddr_t)bp->b_saveaddr;
- off = addr & PGOFSET;
- size = round_page(bp->b_bcount + off);
+ addr = trunc_page((vaddr_t)bp->b_data);
+ off = (vaddr_t)bp->b_data - addr;
+ size = round_page(off + len);
/*
* Note that this is an expanded version of:
@@ -311,7 +311,6 @@
}
bp->b_data = (caddr_t)(kva + off);
- addr = trunc_page(addr);
npf = btoc(size);
while (npf--) {
/* not needed, thanks to PMAP_PREFER() */
@@ -335,7 +334,8 @@
struct buf *bp;
vsize_t len;
{
- vaddr_t addr, off;
+ vaddr_t addr;
+ vsize_t off;
#ifdef DIAGNOSTIC
if ((bp->b_flags & B_PHYS) == 0)
@@ -344,6 +344,8 @@
addr = trunc_page((vaddr_t)bp->b_data);
off = (vaddr_t)bp->b_data - addr;
len = round_page(off + len);
+ pmap_remove(vm_map_pmap(phys_map), addr, addr + len);
+ pmap_update(pmap_kernel());
uvm_km_free_wakeup(phys_map, addr, len);
bp->b_data = bp->b_saveaddr;
bp->b_saveaddr = NULL;
>Release-Note:
>Audit-Trail:
>Unformatted: