freebsd32_ioctl.c

mdf at FreeBSD.org mdf at FreeBSD.org
Thu Oct 7 16:05:52 UTC 2010


I added some more ioctls to those translated by freebsd32_ioctl in my
local tree, and then I started thinking.  If we support all the
various drivers as loadable modules, but the ioctl translation is in
the base kernel, that's a lot of code to have for COMPAT_IA32 that may
never get run.  It would be nice to keep the ioctl argument munging in
the driver, but while it's not hard to check in the driver's ioctl
function if p_sysent is freebsd32_sysent, the code isn't as clean as a
passthrough function like freebsd32_ioctl().

So I was wondering if that would be considered an issue.  Should we
just be adding ioctl argument munging as we go along and not worry
about the size?  Or is there simple way to keep the munging inside the
driver?  Perhaps my making the driver's ioctl look something like:

#ifdef COMPAT_IA32
static int
xxx_ioctl32(struct cdev *dev, u_long com32, caddr_t arg, int flag,
    struct thread *td)
{
	struct xxx_32 *cmd32 = (void *)arg;
	struct xxx cmd;
	u_long com;
	int error;

	CP(*cmd32, cmd, field1);
	/* ... */
	error = xxx_ioctl(dev, com, &cmd, flag, td);
	if (error == 0 && (com & IOC_OUT) != 0) {
		CP(cmd, *cmd32, field1);
		/* ... */
	}
	return (error);
}
#endif /* COMPAT_IA32 */

static int
xxx_ioctl_devsw(struct cdev *dev, u_long com, caddr_t arg, int flag,
    struct thread *td)
{
#ifdef COMPAT_IA32
	if (td->td_proc->p_sysent == &ia32_freebsd_sysvec)
		return (xxx_ioctl32(dev, com, arg, flag, td));
#endif
	return (xxx_ioctl(dev, com, arg, flag, td);
}

... and the check for p_sysent == &ia32_freebsd_sysvec should probably
be a more-correct macro.

Thanks,
matthew


More information about the freebsd-arch mailing list