From owner-freebsd-ia64@FreeBSD.ORG Mon Jun 2 04:31:20 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 23E5F37B404 for ; Mon, 2 Jun 2003 04:31:20 -0700 (PDT) Received: from plim.fujitsu-siemens.com (plim.fujitsu-siemens.com [217.115.66.8]) by mx1.FreeBSD.org (Postfix) with ESMTP id B8DD043FDD for ; Mon, 2 Jun 2003 04:31:17 -0700 (PDT) (envelope-from alan.robinson@fujitsu-siemens.com) Received: from trulli.pdb.fsc.net (new-trulli.pdb.fsc.net [172.25.96.53]) h52BVFv32287; Mon, 2 Jun 2003 13:31:15 +0200 Received: from athen.mch.fsc.net (backbay.mch.fsc.net [172.25.94.188]) by trulli.pdb.fsc.net (8.11.6/8.11.6) with ESMTP id h52BVFV14866; Mon, 2 Jun 2003 13:31:15 +0200 Received: from sanpedro.mch.fsc.net (sanpedro [172.25.95.234]) by athen.mch.fsc.net (8.11.6/8.11.6) with ESMTP id h52BVEI02093; Mon, 2 Jun 2003 13:31:14 +0200 (MDT) Received: (from robin@localhost) by sanpedro.mch.fsc.net (8.9.3p2/8.9.3/Debian 8.9.3-21) id NAA29129; Mon, 2 Jun 2003 13:31:13 +0200 From: Alan Robinson Date: Mon, 2 Jun 2003 13:31:12 +0200 To: Marcel Moolenaar Message-ID: <20030602133112.A3892@fujitsu-siemens.com> References: <20030530132408.A3690@fujitsu-siemens.com> <20030530173029.GB568@dhcp01.pn.xcllnt.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20030530173029.GB568@dhcp01.pn.xcllnt.net>; from marcel@xcllnt.net on Fri, May 30, 2003 at 10:30:29AM -0700 X-sent-by-me: robin@sanpedro 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 Reply-To: Alan.Robinson@fujitsu-siemens.com List-Id: Porting FreeBSD to the IA-64 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Jun 2003 11:31:20 -0000 On Fri, May 30, 2003 at 10:30:29AM -0700, Marcel Moolenaar wrote: > > On Fri, May 30, 2003 at 01:24:08PM +0200, Alan Robinson wrote: > > > > I was playing with a user-land program that read some data out > > of the kernel memory and noticed that the read() return value was > > twice what I was expecting. I think the error is in the mmrw() function > > in file sys/ia64/ia64/mem.c, removing the following lines seems to > > fix the problem. > > > > iov->iov_base = (char *)iov->iov_base + c; > > iov->iov_len -= c; > > uio->uio_offset += c; > > uio->uio_resid -= c; > > > > I had a little look at some of the other sys/ARCH/ARCH/mem.c and some others > > seem to contain the same code so I might be wrong, then again so might the > > ARCHs. > > If you see behaviour that's not particular to ia64, it's probably better > to post to arch@ or current@. More people hang out there, so there's a > bigger chance you get replies. > Maybe I framed my statement incorrectly: I only have access to an i386 (4.6) and an ia64(5.0), the ia64 is the only system that shows the problem. The i386 with 4.6 does NOT have this problem. While looking arround I also saw that the same code is in various ARCH/ARCH/mem.c files, if they really have a problem or not I cannot say. > I don't think there's anything wrong with the lines you think we need to > remove. > I still think they are wrong, there is a uiomove() call which does exactly this fixup for uio several lines before and the iov gets reset at the top. > > Note that the actual data transfered is OK, just the read() return value > > and the /dev/kmem file offset are wrong after returning from the read(). > > It helps if you demonstrate the behaviour with some trivial test program > that people can run too. > You are quite correct. I didn't even say the problem only seems to show up when trying to read info from kld loaded drivers, an example. (I have added the trymem.c source below) madison# kldstat Id Refs Address Size Name 1 3 0xe000000000500000 639448 kernel 2 1 0xa000000004768000 24000 if_fxp.ko read some stuff from the kernel: madison# ./trymem 0xe000000000500000 8 o=e000000000500000, sz=8 lseek xe000000000500000 read(,,x8) rc=x8 lseek(,0,SEEK_CUR) p=xe000000000500008 madison# This seems to be OK. read some stuff from the if_fxp.ko module: madison# ./trymem 0xa000000004768000 8 o=a000000004768000, sz=8 lseek xa000000004768000 read(,,x8) rc=x10 read rc=x10, sz=x8 ! lseek(,0,SEEK_CUR) p=xa000000004768010 lseek(,0,SEEK_CUR) p=xa000000004768010, !=xa000000004768008 ! madison# This is WRONG, the read returns twice the length and the lseek offset is also wrong but consistent with the incorrect rc. After removing the said lines from mem.c trymem works OK for both kernel and if_fxp.ko addresses. Alan -trymem.c-------trymem.c-------trymem.c--------trymem.c--------trymem.c------- #include #include #include #include #include #include #include #define FN "/dev/kmem" int main(int argc, char *argv[]) { int fd, rc; unsigned long o,p; int sz; char buf[16 * 1024]; if (argc < 2) { printf("usage: %s
\n", argv[0]); exit(1); } o = strtoull(argv[1], NULL, 0); sz = strtol(argv[2], NULL, 0); printf("o=%lx, sz=%x\n",o,sz); if (sz > (16 *1024)) { printf("size to large\n"); exit(-1); } fd = open(FN, O_RDONLY); if ( fd < 0) { perror("cannot open " FN); exit(-1); } printf("lseek x%lx\n",o); p = lseek(fd,o,SEEK_SET); if ( o != p ) { printf("lseek x%lx error\n",o); } rc = read(fd,buf,sz); printf("read(,,x%x) rc=x%x\n",sz,rc); if ( rc != sz ) { printf("read rc=x%x, sz=x%x !\n",rc,sz); } p = lseek(fd,(unsigned long)0,SEEK_CUR); printf("lseek(,0,SEEK_CUR) p=x%lx\n",p); if (p != (o + (unsigned long)sz)) { printf("lseek(,0,SEEK_CUR) p=x%lx, !=x%lx !\n",p,(o + (unsigned long)sz)); } close(fd); return (0); } -------------------------------------------------------------------------------