From owner-freebsd-hackers@FreeBSD.ORG Sun May 30 22:59:13 2010 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 7E5521065678 for ; Sun, 30 May 2010 22:59:13 +0000 (UTC) (envelope-from andy@fud.org.nz) Received: from mail-vw0-f54.google.com (mail-vw0-f54.google.com [209.85.212.54]) by mx1.freebsd.org (Postfix) with ESMTP id 1C2478FC16 for ; Sun, 30 May 2010 22:59:12 +0000 (UTC) Received: by vws10 with SMTP id 10so468892vws.13 for ; Sun, 30 May 2010 15:59:12 -0700 (PDT) MIME-Version: 1.0 Received: by 10.220.157.197 with SMTP id c5mr2812326vcx.0.1275258748420; Sun, 30 May 2010 15:32:28 -0700 (PDT) Sender: andy@fud.org.nz Received: by 10.220.90.77 with HTTP; Sun, 30 May 2010 15:32:28 -0700 (PDT) In-Reply-To: <20100530221955.GN83316@deviant.kiev.zoral.com.ua> References: <201005302150.15232.hselasky@c2i.net> <20100530221955.GN83316@deviant.kiev.zoral.com.ua> Date: Mon, 31 May 2010 10:32:28 +1200 X-Google-Sender-Auth: tMIhuUddZdyXZgecvnXG631ktLE Message-ID: From: Andrew Thompson To: Kostik Belousov Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: freebsd-hackers@freebsd.org, Hans Petter Selasky Subject: Re: [FreeBSD 8/9] [64-bit IOCTL] Using the USB stack from a 32-bit application under a 64-bit kernel. 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: Sun, 30 May 2010 22:59:13 -0000 On 31 May 2010 10:19, Kostik Belousov wrote: > On Sun, May 30, 2010 at 09:50:15PM +0200, Hans Petter Selasky wrote: >> Hi, >> >> The USB team in FreeBSD has discussed this issue internally and would li= ke >> some advice how to best resolve the 32 bit to 64 bit IOCTL conversion is= sue. >> >> Sometimes IOCTL requests contain userland pointers of type "void *". Whe= n >> compiled on a 64-bit OS, sizeof(void *) is 8 bytes and when compiled on = a 32- >> bit OS sizeof(void *) is 4 bytes. This size difference makes it impossib= le to >> forward IOCTLs 1:1 from a 32-bit application running under a 64-bit kern= el. >> >> This issue does not only apply to the USB subsystem, but also other kern= el >> IOCTL interfaces. I suggest a more general solution: >> >> typedef uint64_t pvoid64; >> >> When an IOCTL needs to reference pointers in userspace, then they should >> always pad the pointer to 64-bit and use the pvoid64, which could have b= een a >> compiler type, so that we can easily convert to "void *" without using c= asts. >> >> >> When converting 32-bit userland pointers into 64-bit ones, there is no p= ointer >> conversion except for the unsigned expansion and resulting zero-padding.= I >> assume this assumption will always be valid. >> >> >> Please find attached an example patch to make the USB stack in 8 and 9 f= ully >> 64-bit compatible. >> >> >> Any comments are welcome! >> >> >> --HPS >> --- src/sys/dev/usb/usb_ioctl.h =A0 =A0 =A0 2010-02-14 12:03:51.00000000= 0 0000 >> +++ src/sys/dev/usb/usb_ioctl.h =A0 =A0 =A0 2010-02-14 12:03:51.00000000= 0 0000 >> @@ -131,9 +131,10 @@ >> =A0 =A0 =A0 =A0* NOTE: isochronous USB transfer only use one buffer, but= can have >> =A0 =A0 =A0 =A0* multiple frame lengths ! >> =A0 =A0 =A0 =A0*/ >> - =A0 =A0 void =A0**ppBuffer; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* pointer to = userland buffers */ >> - =A0 =A0 uint32_t *pLength; =A0 =A0 =A0 =A0 =A0 =A0 =A0/* pointer to fr= ame lengths, updated >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0* to actual length */ >> + =A0 =A0 uint64_t ppBuffer; =A0 =A0 =A0 =A0 =A0 =A0 =A0/* pointer to 64= -bit userland buffer pointers */ >> + =A0 =A0 uint64_t pLength; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* pointer to 32= -bit frame lengths, which >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0* get updated to the actual length after >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0* the transfer is complete. */ >> =A0 =A0 =A0 uint32_t nFrames; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* number of f= rames */ >> =A0 =A0 =A0 uint32_t aFrames; =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* actual numb= er of frames */ >> =A0 =A0 =A0 uint16_t flags; > > Doesn't this change the existing ABI for 32bit platforms ? > > You may take a look at the sys/net/bpf.c, where the similar > issue is handled for bpf ioctls. To keep the ABI intact, you > would need to define the 32bit ABI structures and define > compat ioctls, then handle the ioctls by converting the structures > and calling the native handler. BIOCSRTIMEOUT32 is a good example. This has been done for other usb ioctls but the above struct has a pointer to an array of pointers in userland which makes it difficult. It isnt copied in with the ioctl so doesnt get the chance to be fixed up. so far, http://people.freebsd.org/~thompsa/linux_usb_amd64_2.diff Andrew