Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Aug 2005 13:48:44 +0200
From:      Roland Smith <rsmith@xs4all.nl>
To:        Miguel Mendez <flynn@energyhq.es.eu.org>
Cc:        freebsd-amd64@freebsd.org
Subject:   Re: 32bit Linux dri apps on FreeBSD/amd64?
Message-ID:  <20050814114844.GA58288@slackbox.xs4all.nl>
In-Reply-To: <20050814113127.7d69af2b.flynn@energyhq.es.eu.org>
References:  <20050814113127.7d69af2b.flynn@energyhq.es.eu.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--FCuugMFkClbJLl1L
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

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?
<snip>
>  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
/usr/src/sys/dev/drm/drm_drv.h):

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

The definition of getunique is:

int DRM(getunique)( DRM_IOCTL_ARGS )
{
        DRM_DEVICE;
        drm_unique_t     u;

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

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

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

        return 0;
}

The DRM_IOCTL_ARGS are:=20

struct cdev *kdev, u_long cmd, caddr_t data, int flags,=20
DRM_STRUCTPROC *p, DRMFILE filp

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) !=3D size)                  \
                return EINVAL;                          \
        kern =3D *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.

Roland
--=20
R.F.Smith (http://www.xs4all.nl/~rsmith/) Please send e-mail as plain text.
public key: http://www.xs4all.nl/~rsmith/pubkey.txt

--FCuugMFkClbJLl1L
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (FreeBSD)

iD8DBQFC/y+cEnfvsMMhpyURAthZAKCezLuXSGTyVzGds0iBgONmyTrQOwCfVCzh
HdgWMAOGrMcgBmsXfV5gJNk=
=hj42
-----END PGP SIGNATURE-----

--FCuugMFkClbJLl1L--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050814114844.GA58288>