32bit Linux dri apps on FreeBSD/amd64?

Roland Smith rsmith at xs4all.nl
Sun Aug 14 11:49:00 GMT 2005

On Sun, Aug 14, 2005 at 11:31:27AM +0200, Miguel Mendez wrote:

> I've installed said port and linux_dri, linux-base-8 and
> linux-XFree86-libs. When trying to run et it fails when
> opening /dev/dri/card0. Can anybody shed some light on what's going on?
>  66553 et.x86   CALL  open(0xffffc890,0x2,0)
>  66553 et.x86   NAMI  "/compat/linux/dev/dri/card0"
>  66553 et.x86   NAMI  "/dev/dri/card0"
>  66553 et.x86   RET   open 8
>  66553 et.x86   CALL  ioctl(0x8,0xc0086401 ,0xffffc990)
>  66553 et.x86   RET   ioctl -1 errno -22 Unknown error: -22
>  66553 et.x86   CALL  close(0x8)
>  66553 et.x86   RET   close 0

It doesn't fail by opening the file, it's the ioctl call that
fails. Errno 22 is EINVAL (invalid argument).

The number of the ioctl can be broken down as follows (see
/usr/src/sys/sys/ioccom.h, /usr/src/sys/dev/drm/drm.h and

0xc0000000 = copy parameters in and out
0x00080000 = argument length <<16 
0x00006400 = ioctl group <<8
0x00000001 = ioctl number 0x01 = DRM_IOCTL_GET_UNIQUE

The definition of getunique is:

int DRM(getunique)( DRM_IOCTL_ARGS )
        drm_unique_t     u;

        DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) );

        if (u.unique_len >= dev->unique_len) {
                if (DRM_COPY_TO_USER(u.unique, dev->unique, dev->unique_len))
                        return DRM_ERR(EFAULT);
        u.unique_len = dev->unique_len;

        DRM_COPY_TO_USER_IOCTL( (drm_unique_t *)data, u, sizeof(u) );

        return 0;


struct cdev *kdev, u_long cmd, caddr_t data, int flags, 

As you can see below, DRM_COPY_FROM_USER_IOCTL can return EINVAL:

#define DRM_COPY_FROM_USER_IOCTL(kern, user, size) \
        if ( IOCPARM_LEN(cmd) != size)                  \
                return EINVAL;                          \
        kern = *user;

IOCPARM_LEN(cmd) is cmd>>16 & 0x1fff, which in this case gives 8 bytes.

And here is the error, I think. Because drm_unique_t is defined as:

typedef struct drm_unique {
        size_t unique_len;        /**< Length of unique */
        char   *unique;           /**< Unique name for driver instantiation */
} drm_unique_t;

On amd64, both size_t and char* are 8 bytes. So sizeof(drm_unique_t) is
16 bytes on amd64.

To fix this, the drm driver would have to know if ioctls were being made
by a 32-bit program, and adjust the parameter size tests accordingly. I
do not know if that is possible.

R.F.Smith (http://www.xs4all.nl/~rsmith/) Please send e-mail as plain text.
public key: http://www.xs4all.nl/~rsmith/pubkey.txt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-amd64/attachments/20050814/e0b9a4f9/attachment.bin

More information about the freebsd-amd64 mailing list