From owner-freebsd-hackers Tue Jul 29 20:23:32 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id UAA03281 for hackers-outgoing; Tue, 29 Jul 1997 20:23:32 -0700 (PDT) Received: from genesis.atrad.adelaide.edu.au (genesis.atrad.adelaide.edu.au [129.127.96.120]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id UAA03271 for ; Tue, 29 Jul 1997 20:23:22 -0700 (PDT) Received: (from msmith@localhost) by genesis.atrad.adelaide.edu.au (8.8.5/8.7.3) id MAA17715; Wed, 30 Jul 1997 12:52:19 +0930 (CST) From: Michael Smith Message-Id: <199707300322.MAA17715@genesis.atrad.adelaide.edu.au> Subject: Re: Location of copyin() and copyout().. In-Reply-To: <199707300310.UAA12221@implode.root.com> from David Greenman at "Jul 29, 97 08:10:28 pm" To: dg@root.com Date: Wed, 30 Jul 1997 12:52:18 +0930 (CST) Cc: msmith@atrad.adelaide.edu.au, freebsd-hackers@FreeBSD.ORG X-Mailer: ELM [version 2.4ME+ PL28 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk David Greenman stands accused of saying: >>> I don't understand the distinction you're making. copyout *always* runs in >>>the (kernel) context of a user process and the destination is always process >>>(as opposed to kernel) memory. Please explain. > > > >If I am writing an ABI emulation function that exchanges data with the > >emulated binary in one format, but need to pass the data in a > >different format to/from the function(s) in the kernel which provide > >the required functionality, I have to perform the format translation > >in buffers in kernel space. > > > >If the kernel function(s) use copyin/copyout, they cannot access these > >buffers, and thus the emulation cannot be performed. > > I still don't understand. copyin/out is only for copying between the kernel > and user memory. If this is what you're doing and you don't need the extra > features of uiomove (which is designed to do piecemeal copies by keeping track > of offsets/lengths in a struct uio), then copyin/out is the function to use. > If on the other hand you're copying from kernel<->kernel, then you can just > use bcopy. I'm afraid that I started reading this thread rather late into it > and don't have the original context...so what are we talking about? :-) AAARGH! 8) 8) 8) How about a specific example, the one that bloodied my nose a little while back. The FreeBSD kernel function i386_set_ldt() uses copyin() to retrieve its arguments from the user process. Linux uses the i386_modify_ldt syscall to perform the same functionality. It has a different set of arguments, which convey essentially the same information. So, I write a function linux_i386_modify_ldt(), which lives in the linux emulation module. It takes the Linux i386_modify_ldt() syscall, converts the arguments to the right format, and tries to call i386_set_ldt(). Only it _can't_, because the latter is using copyin(), and cannot access the argument structure in kernel space. If i386_set_ldt() used uiomove, I could construct a uio structure in linux_i386_modify_ldt() that told uimove that the source address was in kernel space, and i386_set_ldt() wouldn't have to care. So, what I am _begging_ is : do *not* use copyin()/copyout() unless you are absolutely, utterly, 110% certain that you will only _ever_ be talking directly to user memory. This boils down to not ever using copyin/out to handle data in device drivers, syscall handlers, protocol stacks, etc., ie. basically not at all. -- ]] Mike Smith, Software Engineer msmith@gsoft.com.au [[ ]] Genesis Software genesis@gsoft.com.au [[ ]] High-speed data acquisition and (GSM mobile) 0411-222-496 [[ ]] realtime instrument control. (ph) +61-8-8267-3493 [[ ]] Unix hardware collector. "Where are your PEZ?" The Tick [[