Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/sparc64 - fix corner case bugs around the s...
details: https://anonhg.NetBSD.org/src/rev/4f07b6e6fbb4
branches: trunk
changeset: 749758:4f07b6e6fbb4
user: nakayama <nakayama%NetBSD.org@localhost>
date: Mon Dec 07 11:28:37 2009 +0000
description:
- fix corner case bugs around the segment offsets.
- make sure that on error condition we return "no valid mappings".
diffstat:
sys/arch/sparc64/sparc64/machdep.c | 38 +++++++++++++++++++++++++++-----------
1 files changed, 27 insertions(+), 11 deletions(-)
diffs (108 lines):
diff -r cab3a4a4a06b -r 4f07b6e6fbb4 sys/arch/sparc64/sparc64/machdep.c
--- a/sys/arch/sparc64/sparc64/machdep.c Mon Dec 07 11:24:30 2009 +0000
+++ b/sys/arch/sparc64/sparc64/machdep.c Mon Dec 07 11:28:37 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.249 2009/12/02 10:18:42 nakayama Exp $ */
+/* $NetBSD: machdep.c,v 1.250 2009/12/07 11:28:37 nakayama Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.249 2009/12/02 10:18:42 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.250 2009/12/07 11:28:37 nakayama Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@@ -1037,7 +1037,6 @@
/*
* We always use just one segment.
*/
- map->dm_mapsize = buflen;
i = 0;
map->dm_segs[i].ds_addr = 0UL;
map->dm_segs[i].ds_len = 0;
@@ -1049,23 +1048,24 @@
incr = min(sgsize, incr);
(void) pmap_extract(pmap_kernel(), vaddr, &pa);
- sgsize -= incr;
- vaddr += incr;
if (map->dm_segs[i].ds_len == 0)
map->dm_segs[i].ds_addr = pa;
if (pa == (map->dm_segs[i].ds_addr + map->dm_segs[i].ds_len)
&& ((map->dm_segs[i].ds_len + incr) <= map->dm_maxsegsz)) {
/* Hey, waddyaknow, they're contiguous */
map->dm_segs[i].ds_len += incr;
- incr = PAGE_SIZE;
- continue;
+ } else {
+ if (++i >= map->_dm_segcnt)
+ return (EFBIG);
+ map->dm_segs[i].ds_addr = pa;
+ map->dm_segs[i].ds_len = incr;
}
- if (++i >= map->_dm_segcnt)
- return (EFBIG);
- map->dm_segs[i].ds_addr = pa;
- map->dm_segs[i].ds_len = incr = PAGE_SIZE;
+ sgsize -= incr;
+ vaddr += incr;
+ incr = PAGE_SIZE;
}
map->dm_nsegs = i + 1;
+ map->dm_mapsize = buflen;
/* Mapping is bus dependent */
return (0);
}
@@ -1081,8 +1081,15 @@
int i;
size_t len;
+ /*
+ * Make sure that on error condition we return "no valid mappings".
+ */
+ map->dm_nsegs = 0;
KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
+ if (m->m_pkthdr.len > map->_dm_size)
+ return EINVAL;
+
/* Record mbuf for *_unload */
map->_dm_type = _DM_TYPE_MBUF;
map->_dm_source = (void *)m;
@@ -1194,6 +1201,10 @@
struct proc *p = uio->uio_lwp->l_proc;
struct pmap *pm;
+ /*
+ * Make sure that on error condition we return "no valid mappings".
+ */
+ map->dm_nsegs = 0;
KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
if (uio->uio_segflg == UIO_USERSPACE) {
@@ -1346,16 +1357,21 @@
if (offset < PAGE_SIZE) {
start = VM_PAGE_TO_PHYS(pg) + offset;
+ size -= offset;
if (size > len)
size = len;
cache_flush_phys(start, size, 0);
len -= size;
+ if (len == 0)
+ goto done;
+ offset = 0;
continue;
}
offset -= size;
}
}
}
+ done:
if (ops & BUS_DMASYNC_POSTWRITE) {
/* Nothing to do. Handled by the bus controller. */
}
Home |
Main Index |
Thread Index |
Old Index