From owner-freebsd-ia64@FreeBSD.ORG Tue Jun 3 01:04:15 2003 Return-Path: Delivered-To: freebsd-ia64@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 570B737B405 for ; Tue, 3 Jun 2003 01:04:15 -0700 (PDT) Received: from ns1.xcllnt.net (209-128-86-226.BAYAREA.NET [209.128.86.226]) by mx1.FreeBSD.org (Postfix) with ESMTP id 357A243F3F for ; Tue, 3 Jun 2003 01:04:14 -0700 (PDT) (envelope-from marcel@xcllnt.net) Received: from dhcp01.pn.xcllnt.net (dhcp01.pn.xcllnt.net [192.168.4.201]) by ns1.xcllnt.net (8.12.9/8.12.9) with ESMTP id h5384Dwk007387; Tue, 3 Jun 2003 01:04:13 -0700 (PDT) (envelope-from marcel@piii.pn.xcllnt.net) Received: from dhcp01.pn.xcllnt.net (localhost [127.0.0.1]) by dhcp01.pn.xcllnt.net (8.12.9/8.12.9) with ESMTP id h5384DfA003511; Tue, 3 Jun 2003 01:04:13 -0700 (PDT) (envelope-from marcel@dhcp01.pn.xcllnt.net) Received: (from marcel@localhost) by dhcp01.pn.xcllnt.net (8.12.9/8.12.9/Submit) id h5384DrB003510; Tue, 3 Jun 2003 01:04:13 -0700 (PDT) Date: Tue, 3 Jun 2003 01:04:13 -0700 From: Marcel Moolenaar To: Alan Robinson Message-ID: <20030603080413.GA3382@dhcp01.pn.xcllnt.net> 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> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="45Z9DzgjV8m4Oswq" Content-Disposition: inline In-Reply-To: <20030603085052.A2520@fujitsu-siemens.com> User-Agent: Mutt/1.5.4i cc: freebsd-ia64@freebsd.org Subject: Re: /dev/kmem read return value is double requested value X-BeenThere: freebsd-ia64@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Porting FreeBSD to the IA-64 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Jun 2003 08:04:15 -0000 --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 //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--