[FreeBSD 8/9] [64-bit IOCTL] Using the USB stack from a 32-bit application under a 64-bit kernel.

Kostik Belousov kostikbel at gmail.com
Sun May 30 22:20:05 UTC 2010


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 like 
> some advice how to best resolve the 32 bit to 64 bit IOCTL conversion issue.
> 
> Sometimes IOCTL requests contain userland pointers of type "void *". When 
> 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 impossible to 
> forward IOCTLs 1:1 from a 32-bit application running under a 64-bit kernel.
> 
> This issue does not only apply to the USB subsystem, but also other kernel 
> 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 been a 
> compiler type, so that we can easily convert to "void *" without using casts.
> 
> 
> When converting 32-bit userland pointers into 64-bit ones, there is no pointer 
> 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 fully 
> 64-bit compatible.
> 
> 
> Any comments are welcome!
> 
> 
> --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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20100530/bbf78675/attachment.pgp


More information about the freebsd-hackers mailing list