Date: Mon, 31 May 2010 01:19:55 +0300 From: Kostik Belousov <kostikbel@gmail.com> To: Hans Petter Selasky <hselasky@c2i.net> Cc: freebsd-hackers@freebsd.org Subject: Re: [FreeBSD 8/9] [64-bit IOCTL] Using the USB stack from a 32-bit application under a 64-bit kernel. Message-ID: <20100530221955.GN83316@deviant.kiev.zoral.com.ua> In-Reply-To: <201005302150.15232.hselasky@c2i.net> References: <201005302150.15232.hselasky@c2i.net>
next in thread | previous in thread | raw e-mail | index | archive | help
--UXm1vU+X4IBWGr3e Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sun, May 30, 2010 at 09:50:15PM +0200, Hans Petter Selasky wrote: > Hi, >=20 > The USB team in FreeBSD has discussed this issue internally and would lik= e=20 > some advice how to best resolve the 32 bit to 64 bit IOCTL conversion iss= ue. >=20 > Sometimes IOCTL requests contain userland pointers of type "void *". When= =20 > 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 impossibl= e to=20 > forward IOCTLs 1:1 from a 32-bit application running under a 64-bit kerne= l. >=20 > This issue does not only apply to the USB subsystem, but also other kerne= l=20 > IOCTL interfaces. I suggest a more general solution: >=20 > typedef uint64_t pvoid64; >=20 > When an IOCTL needs to reference pointers in userspace, then they should= =20 > always pad the pointer to 64-bit and use the pvoid64, which could have be= en a=20 > compiler type, so that we can easily convert to "void *" without using ca= sts. >=20 >=20 > When converting 32-bit userland pointers into 64-bit ones, there is no po= inter=20 > conversion except for the unsigned expansion and resulting zero-padding. = I=20 > assume this assumption will always be valid. >=20 >=20 > Please find attached an example patch to make the USB stack in 8 and 9 fu= lly=20 > 64-bit compatible. >=20 >=20 > Any comments are welcome! >=20 >=20 > --HPS > --- src/sys/dev/usb/usb_ioctl.h 2010-02-14 12:03:51.000000000 0000 > +++ src/sys/dev/usb/usb_ioctl.h 2010-02-14 12:03:51.000000000 0000 > @@ -131,9 +131,10 @@ > * NOTE: isochronous USB transfer only use one buffer, but can have > * multiple frame lengths ! > */ > - void **ppBuffer; /* pointer to userland buffers */ > - uint32_t *pLength; /* pointer to frame lengths, updated > - * to actual length */ > + uint64_t ppBuffer; /* pointer to 64-bit userland buffer pointers */ > + uint64_t pLength; /* pointer to 32-bit frame lengths, which > + * get updated to the actual length after > + * the transfer is complete. */ > uint32_t nFrames; /* number of frames */ > uint32_t aFrames; /* actual number of frames */ > 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. --UXm1vU+X4IBWGr3e Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkwC5IsACgkQC3+MBN1Mb4g34gCg3UIvYPAQHJhjmWKZDxs0XHD/ rnsAn3JDJB7ZI3nuOHgmPLkpUp8rGTpk =QEGc -----END PGP SIGNATURE----- --UXm1vU+X4IBWGr3e--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100530221955.GN83316>