summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-06-04 21:56:10 +0000
committermarcel <marcel@FreeBSD.org>2003-06-04 21:56:10 +0000
commit23fb7b1d8ae16786c3d0b8f3981f6fd027669b2e (patch)
treed0abb41f35b15c8128a7ae033c88a20a4d858a65 /sys/ia64
parent482a35058c1ec5165650b6b75eab0e46a3cafd33 (diff)
downloadFreeBSD-src-23fb7b1d8ae16786c3d0b8f3981f6fd027669b2e.zip
FreeBSD-src-23fb7b1d8ae16786c3d0b8f3981f6fd027669b2e.tar.gz
Fix the dreaded double counting that was present on alpha as well and
got fixed two weeks after the ia64 version was copied from the alpha version (see rev 1.32 of sys/alpha/alpha/mem.c). As such, we were missing the same continue as on alpha. While here, add a default case for the device minor switch and do some general style(9) cleanups. WARNING: this file still has bugs. When reading from region 6 or region 7, we don't validate the physical address. One can trivially cause a machine check by trying to read from address 0xFFFFFFFFFFFFFFF0 or something that uses the unimplemented physical address bits. Reported by: Alan Robinson <alan.robinson@fujitsu-siemens.com>
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/mem.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/sys/ia64/ia64/mem.c b/sys/ia64/ia64/mem.c
index 75b65ae..cd4f3b1 100644
--- a/sys/ia64/ia64/mem.c
+++ b/sys/ia64/ia64/mem.c
@@ -139,12 +139,11 @@ mmopen(dev_t dev, int flags, int fmt, struct thread *td)
static int
mmrw(dev_t dev, struct uio *uio, int flags)
{
- vm_offset_t o, v;
- int c = 0;
struct iovec *iov;
- int error = 0, rw;
- vm_offset_t addr, eaddr;
+ vm_offset_t addr, eaddr, o, v;
+ int c, error, rw;
+ error = 0;
while (uio->uio_resid > 0 && !error) {
iov = uio->uio_iov;
if (iov->iov_len == 0) {
@@ -154,6 +153,7 @@ mmrw(dev_t dev, struct uio *uio, int flags)
panic("mmrw");
continue;
}
+
switch (minor(dev)) {
/* minor device 0 is physical memory */
@@ -161,7 +161,8 @@ mmrw(dev_t dev, struct uio *uio, int flags)
v = uio->uio_offset;
kmemphys:
/* Allow reads only in RAM. */
- rw = (uio->uio_rw == UIO_READ) ? VM_PROT_READ : VM_PROT_WRITE;
+ rw = (uio->uio_rw == UIO_READ)
+ ? VM_PROT_READ : VM_PROT_WRITE;
if ((ia64_pa_access(v) & rw) != rw) {
error = EFAULT;
c = 0;
@@ -170,8 +171,7 @@ kmemphys:
o = uio->uio_offset & PAGE_MASK;
c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
- error =
- uiomove((caddr_t)IA64_PHYS_TO_RR7(v), c, uio);
+ error = uiomove((caddr_t)IA64_PHYS_TO_RR7(v), c, uio);
continue;
/* minor device 1 is kernel memory */
@@ -184,22 +184,26 @@ kmemphys:
}
c = min(iov->iov_len, MAXPHYS);
+
/*
- * Make sure that all of the pages are currently resident so
- * that we don't create any zero-fill pages.
+ * Make sure that all of the pages are currently
+ * resident so that we don't create any zero-fill
+ * pages.
*/
addr = trunc_page(v);
eaddr = round_page(v + c);
- for (; addr < eaddr; addr += PAGE_SIZE)
- if (pmap_extract(kernel_pmap, addr) == 0) {
- return EFAULT;
- }
- if (!kernacc((caddr_t)v, c,
- uio->uio_rw == UIO_READ ?
- VM_PROT_READ : VM_PROT_WRITE)) {
- return (EFAULT);
+ for (; addr < eaddr; addr += PAGE_SIZE) {
+ if (pmap_extract(kernel_pmap, addr) == 0)
+ return (EFAULT);
}
+ if (!kernacc((caddr_t)v, c, (uio->uio_rw == UIO_READ)
+ ? VM_PROT_READ : VM_PROT_WRITE))
+ return (EFAULT);
error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+ default:
+ return (ENODEV);
}
if (error)
OpenPOWER on IntegriCloud