Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jun 2003 01:04:13 -0700
From:      Marcel Moolenaar <marcel@xcllnt.net>
To:        Alan Robinson <alan.robinson@fujitsu-siemens.com>
Cc:        freebsd-ia64@freebsd.org
Subject:   Re: /dev/kmem read return value is double requested value
Message-ID:  <20030603080413.GA3382@dhcp01.pn.xcllnt.net>
In-Reply-To: <20030603085052.A2520@fujitsu-siemens.com>
References:  <20030530132408.A3690@fujitsu-siemens.com> <20030530173029.GB568@dhcp01.pn.xcllnt.net> <20030602133112.A3892@fujitsu-siemens.com> <20030602215156.GB1345@dhcp01.pn.xcllnt.net> <20030603085052.A2520@fujitsu-siemens.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--45Z9DzgjV8m4Oswq
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, Jun 03, 2003 at 08:50:52AM +0200, Alan Robinson wrote:
> > I'll take a look at it when I have a spare cycle.
> > 
> I compared the ia64/i386 mmrw() and another answer is to add 
> a 'continue' after the /dev/kmem uiomove just like in i386.

Spot on. See sys/alpha/alpha/mem.c rev. 1.32. And also rev 1.24.
mmrw() has a history of double counting :-(

> I bet the 4 lines are still junk left over from a previous life
> when the uiomove was a copyout?

Dunno. It may be leftovers from when <machine>/<machine>/mem.c had
to handle /dev/zero, /dev/urandom and the likes.

There's another bug in sys/ia64/ia64/mem.c: we're missing a default
case for the minor device number...

I have a cleaned version ready to be committed. I need to wait for
my box to free up.

Thanks!

PS: attached the (untested) patch currently in my tree.

-- 
 Marcel Moolenaar	  USPA: A-39004		 marcel@xcllnt.net

--45Z9DzgjV8m4Oswq
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="mem.diff"

Index: mem.c
===================================================================
RCS file: /home/ncvs/src/sys/ia64/ia64/mem.c,v
retrieving revision 1.13
diff -u -r1.13 mem.c
--- mem.c	25 Mar 2003 00:07:03 -0000	1.13
+++ mem.c	3 Jun 2003 07:52:40 -0000
@@ -139,12 +139,11 @@
 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 @@
 				panic("mmrw");
 			continue;
 		}
+
 		switch (minor(dev)) {
 
 /* minor device 0 is physical memory */
@@ -161,7 +161,8 @@
 			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 @@
 
 			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 @@
 			}
 
 			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)

--45Z9DzgjV8m4Oswq--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030603080413.GA3382>