Date: Wed, 30 Jul 1997 12:52:18 +0930 (CST) From: Michael Smith <msmith@atrad.adelaide.edu.au> To: dg@root.com Cc: msmith@atrad.adelaide.edu.au, freebsd-hackers@FreeBSD.ORG Subject: Re: Location of copyin() and copyout().. Message-ID: <199707300322.MAA17715@genesis.atrad.adelaide.edu.au> In-Reply-To: <199707300310.UAA12221@implode.root.com> from David Greenman at "Jul 29, 97 08:10:28 pm"
next in thread | previous in thread | raw e-mail | index | archive | help
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 [[
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199707300322.MAA17715>