From owner-freebsd-hackers@FreeBSD.ORG Thu Jan 15 19:22:45 2009 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D6BDA106564A for ; Thu, 15 Jan 2009 19:22:45 +0000 (UTC) (envelope-from gerryw@compvia.com) Received: from mail01.compvia.com (mail01.compvia.com [12.147.132.91]) by mx1.freebsd.org (Postfix) with ESMTP id 7D8FB8FC12 for ; Thu, 15 Jan 2009 19:22:45 +0000 (UTC) (envelope-from gerryw@compvia.com) Received: from [10.10.40.235] ([10.10.40.235]) by mail01.compvia.com (Kerio MailServer 6.5.1); Thu, 15 Jan 2009 13:22:42 -0600 To: "Alexej Sokolov" From: "Gerry Weaver" In-Reply-To: 671bb5fc0901151031w2da249ebu273dfb9429f82ac7@mail.gmail.com Message-ID: <20090115192242.4fce7e00@mail01.compvia.com> Date: Thu, 15 Jan 2009 13:22:42 -0600 X-Mailer: Kerio MailServer 6.5.1 WebMail X-User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: freebsd-hackers@freebsd.org Subject: Re: How to access kernel memory from user space X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Jan 2009 19:22:46 -0000 =5F=5F=5F=5F=5F =20 From: Alexej Sokolov [mailto:bsd.quest@googlemail.com] To: Gerry Weaver [mailto:gerryw@compvia.com] Cc: freebsd-hackers@freebsd.org Sent: Thu, 15 Jan 2009 12:31:00 -0600 Subject: Re: How to access kernel memory from user space 2008/12/23 Gerry Weaver Hello All, =20 I am working on a driver that collects various network statistics via = pfil. I have a simple array of structures that I use to store the statis= tics. I also have a user space process that needs to collect these stati= stics every second or so. A copy operation from kernel to user space wou= ld be too expensive. Is there a mechanism that would allow me to gain di= rect access to my kernel array from user space=3F The user process would= only need read access. It seems like maybe this could be done with mmap= , but since this is not a character driver, there is no device file etc.= . I'm a newbie, so I apologize if this is something that should be obvio= us. =20 =20 Thanks in advance, Gerry =5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F= =5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.= org" Hi,=20 some times ago I solve this task. That's my solution in a system call (w= hithout cdev).=20 Thanx in advance for founded mistakes and possible bugs (-: #include #include #include #include #include #include #include #include #include =20 #include #include #include #include #include #include =20 =20 /* Arguments for syscall */ struct args { =20 /* Pointer to allocated Buffer */ unsigned int *p; };=20 =20 /* String to be located in maped buffer */ const char *str =3D "BSD IS SEXY"; =20 /* Syscall func */ static int=20 syscf(struct thread *td, void *sa) { int error; struct args *uap; =20 vm=5Foffset=5Ft addr; /* Kernel space address */ vm=5Foffset=5Ft user=5Faddr; /* User space address */ =20 struct proc *procp =3D (struct proc *)td->td=5Fproc; =20 struct vmspace *vms =3D procp->p=5Fvmspace; =20 =20 uap =3D (struct args *)sa; =20 PROC=5FLOCK(procp); user=5Faddr =3D round=5Fpage((vm=5Foffset=5Ft)vms->vm=5Fdaddr += =20 lim=5Fmax(procp, RLIMIT=5FDATA)); PROC=5FUNLOCK(procp); =20 MALLOC(addr, vm=5Foffset=5Ft, PAGE=5FSIZE, M=5FDEVBUF, M=5FWAITO= K | M=5FZERO); =20 vm=5Fmap=5Fentry=5Ft myentry; vm=5Fobject=5Ft myobject; vm=5Fpindex=5Ft mypindex; vm=5Fprot=5Ft myprot; boolean=5Ft mywired; vm=5Fooffset=5Ft objoffset; vm=5Fmap=5Flookup(&kmem=5Fmap, addr, VM=5FPROT=5FALL, &myentry, &myobject, &mypindex, &myprot, &mywire= d); /* OUT */ vm=5Fmap=5Flookup=5Fdone(kmem=5Fmap, myentry); =20 printf("---> Syscall: hint for allocating space =3D 0x%X\n", add= r); =20 if (myobject =3D=3D kmem=5Fobject){ printf("---> Syscall: Yes, it is kmem=5Fobj! \n"); } =20 /* Offset in vm=5Fobject */ =20 objoffset =3D addr - myentry->start + myentry->offset; =20 printf("------> Syscall: Object offset =3D 0x%X \n", (unsigned i= nt)objoffset); =20 /* * Try to map kernel buffer to user space =20 */ vm=5Fobject=5Freference(myobject); /* NEEDED Increment vm=5Fobj = references */ error =3D vm=5Fmap=5Ffind(&vms->vm=5Fmap, myobject, objoffset, (= vm=5Foffset=5Ft *)&user=5Faddr,=20 PAGE=5FSIZE, TRUE, VM=5FPROT=5FRW, VM=5FPROT= =5FRW,=20 MAP=5FENTRY=5FNOFAULT); =20 if (error =3D=3D KERN=5FSUCCESS) { /* copy string using kernel address */ size=5Ft len; copystr(str, (void *)addr, 12, &len);=20 =20 /*=20 * Tell to user process it's user space address=20 */ *uap->p =3D user=5Faddr; =20 /*=20 * Try to read the string using user space address */ =20 printf("String: %s\n", (char *)*uap->p);=20 =20 printf("---> Syscall: user=5Faddr for allocating space = =3D 0x%X\n", user=5Faddr); } =20 return (0); } =20 /* Sysent entity for syscall */ static struct sysent sc=5Fsysent =3D { 1, /* Number of arg= uments */ syscf /* Syscall function *= / }; =20 /* Offset in sysent[] */ static int offset =3D NO=5FSYSCALL; =20 /* Loader */ static int load (struct module *m, int cmd, void *something) { int error =3D 0; switch(cmd){ case MOD=5FLOAD: printf("Module with sysc loaded. Offset =3D %d= \n", offset); break; =20 case MOD=5FUNLOAD: printf("Module with sysc unloaded. Offset =3D %d= \n", offset); break; =20 default: error =3D EOPNOTSUPP; break; } return (error); } =20 /* Syscall macro*/ SYSCALL=5FMODULE(fiveg=5Fsysc, &offset, &sc=5Fsysent, load, NULL); =20 If needed, I can post user space program.=20 Hi, This looks like a very nice solution. I would like to see the user space= code very much. I really appreciate your help! Thanks Again, Gerry =20