Bug 116181

Summary: /dev/io-related io access permissions are not propagated to every thread in a process
Product: Base System Reporter: Kyle Larose <kmlarose>
Component: threadsAssignee: attilio
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 6.2-RELEASE   
Hardware: Any   
OS: Any   

Description Kyle Larose 2007-09-07 17:50:01 UTC
Some background:

Opening /dev/io is supposed to give permission to use instructions like
inb/outb. If a process doesn't have this permission, it will fault on
execution of those instructions. The permission is controlled through
the IOPL flag in the EEFLAGS register. On opening /dev/io, it sets the
permission like so:

 64         td->td_frame->tf_eflags |= PSL_IOPL;

(from sys/i386/i386/io.c)

Now, when a process opens a file, its fd is supposed to be shared across
every thread in the process. Consequently, one would think that the
permissions associated with this fd would also be shared. However, this
is not the case. 

It seems that only threads who are descendents of a thread that had
/dev/io opened when they were created. Threads created by threads without
the permissioin will not get the permission. Threads which exist at the
time /dev/io is opened, other than the opening thread, will also not get
the permission. So, a process will need to make sure that every thread
needing IO permissions has an ancestor that opened /dev/io before the
thread was created. This seems sub-optimal, and contrary to the spirit
of sharing file descriptors over an entire process.

To make the problem worse, closing /dev/io works in the same manner:
 74         td->td_frame->tf_eflags &= ~PSL_IOPL;

This leads me to believe that every thread which inherited permissions
from an ancestor thread will keep the permissions, despite the closure
of /dev/io. In fact, since the fd is shared across the process, a thread
without the permissions could close the file. I think that, for the same
reason that the flag isn't propagated to all threads on opening /dev/io,
it will in turn not be unset in all threads when closing /dev/io. So, we
could have a process which doesn't have /dev/io open still have IO
permissions. This would be a security hole.

I also looked at how the linux compat code handles iopl for i386, and it
is similar to this (it sets some flags in td->frame), so the issue might
also crop up there.

How-To-Repeat: I haven't tested the removal of permissions portion, but I have tested
that permissions aren't shared across the processes.

I wrote a program that starts a thread, opens /dev/io in the main thread,
then tries to write to the serial port in the second thread. It gives a
bus error.

include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <machine/cpufunc.h>
pthread_cond_t dev_cond;
pthread_mutex_t dev_lock;
pthread_t thr;
void io_main();
void do_write();
void *second_thread(void*);

int main(int argc, char ** argv)
{
    if(pthread_cond_init(&dev_cond, NULL))
    {
	printf("Error initializing condition var.\n");
	return 1;
    }
    if(pthread_mutex_init(&dev_lock, NULL))
    {
	printf("Error initializing mutex.\n");
	return 1;
    }
    io_main();
    return 0;
}

void do_write()
{
    outb(0x378, 'a');
    printf("done\n");
}

void io_main()
{ 
    int fd;
    pthread_mutex_lock(&dev_lock);
    if(pthread_create(&thr,NULL, second_thread, NULL))
    {
	printf("Error creating second thread\n");
	exit(1);
    }
    if((fd = open("/dev/io", O_RDWR)) == -1)
    {
	    printf("Error opening /dev/io: %i\n", fd);
	    exit(1);
    }
    pthread_cond_wait(&dev_cond,&dev_lock);
    close(fd);
}
void *second_thread(void *args)
{
    int fd;
    pthread_mutex_lock(&dev_lock);
    printf("Performing write in secondary...\n");
    do_write();
    pthread_mutex_unlock(&dev_lock);
    pthread_cond_signal(&dev_cond);
    return 0;
}
Comment 1 veep 2007-09-10 13:52:28 UTC
It should be noted that I tested the example app with -lthr (so it *could*
be a bug with the threading library, though it still sounds more like a
problem with the kernel to me).

-- 
Kyle Larose
Vice President,
University of Waterloo Computer Science Club.
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2008-01-15 05:14:10 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-threads

Reclassify.
Comment 3 dfilter service freebsd_committer freebsd_triage 2010-04-28 16:38:11 UTC
Author: attilio
Date: Wed Apr 28 15:38:01 2010
New Revision: 207329
URL: http://svn.freebsd.org/changeset/base/207329

Log:
  - Extract the IODEV_PIO interface from ia64 and make it MI.
    In the end, it does help fixing /dev/io usage from multithreaded
    processes.
  - On i386 and amd64 the old behaviour is kept but multithreaded
    processes must use the new interface in order to work well.
  - Support for the other architectures is greatly improved, where
    necessary, by the necessity to define very small things now.
  
  Manpage update will happen shortly.
  
  Sponsored by:	Sandvine Incorporated
  PR:		threads/116181
  Reviewed by:	emaste, marcel
  MFC after:	3 weeks

Added:
  head/sys/dev/io/iodev.h   (contents, props changed)
Modified:
  head/sys/amd64/amd64/io.c
  head/sys/amd64/include/iodev.h
  head/sys/dev/io/iodev.c
  head/sys/i386/i386/io.c
  head/sys/i386/include/iodev.h
  head/sys/ia64/ia64/iodev_machdep.c
  head/sys/ia64/include/iodev.h

Modified: head/sys/amd64/amd64/io.c
==============================================================================
--- head/sys/amd64/amd64/io.c	Wed Apr 28 15:15:06 2010	(r207328)
+++ head/sys/amd64/amd64/io.c	Wed Apr 28 15:38:01 2010	(r207329)
@@ -28,60 +28,32 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/priv.h>
 #include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/systm.h>
 
-#include <machine/db_machdep.h>
 #include <machine/frame.h>
-#include <machine/psl.h>
-#include <machine/specialreg.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
 #include <machine/iodev.h>
+#include <machine/psl.h>
 
-/* ARGSUSED */
 int
-ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
-    struct thread *td)
+iodev_open(struct thread *td)
 {
-	int error;
-
-	error = priv_check(td, PRIV_IO);
-	if (error != 0)
-		return (error);
-	error = securelevel_gt(td->td_ucred, 0);
-	if (error != 0)
-		return (error);
 
 	td->td_frame->tf_rflags |= PSL_IOPL;
-
 	return (0);
 }
 
-/* ARGSUSED */
 int
-ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
-    struct thread *td)
+iodev_close(struct thread *td)
 {
-	td->td_frame->tf_rflags &= ~PSL_IOPL;
 
+	td->td_frame->tf_rflags &= ~PSL_IOPL;
 	return (0);
 }
 
 /* ARGSUSED */
 int
-ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused,
-    int fflag __unused, struct thread *td __unused)
+iodev_ioctl(u_long cmd __unused, caddr_t data __unused)
 {
 
-	return (ENXIO);
+	return (ENOIOCTL);
 }

Modified: head/sys/amd64/include/iodev.h
==============================================================================
--- head/sys/amd64/include/iodev.h	Wed Apr 28 15:15:06 2010	(r207328)
+++ head/sys/amd64/include/iodev.h	Wed Apr 28 15:38:01 2010	(r207329)
@@ -25,7 +25,22 @@
  *
  * $FreeBSD$
  */
+#ifndef _MACHINE_IODEV_H_
+#define	_MACHINE_IODEV_H_
 
-d_open_t	ioopen;
-d_close_t	ioclose;
-d_ioctl_t	ioioctl;
+#ifdef _KERNEL
+#include <machine/cpufunc.h>
+
+#define	iodev_read_1	inb
+#define	iodev_read_2	inw
+#define	iodev_read_4	inl
+#define	iodev_write_1	outb
+#define	iodev_write_2	outw
+#define	iodev_write_4	outl
+
+int	 iodev_open(struct thread *td);
+int	 iodev_close(struct thread *td);
+int	 iodev_ioctl(u_long cmd, caddr_t data);
+
+#endif /* _KERNEL */
+#endif /* _MACHINE_IODEV_H_ */

Modified: head/sys/dev/io/iodev.c
==============================================================================
--- head/sys/dev/io/iodev.c	Wed Apr 28 15:15:06 2010	(r207328)
+++ head/sys/dev/io/iodev.c	Wed Apr 28 15:38:01 2010	(r207329)
@@ -30,22 +30,27 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/conf.h>
-#include <sys/fcntl.h>
 #include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
+#include <sys/ioccom.h>
 #include <sys/module.h>
-#include <sys/mutex.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
-#include <sys/signalvar.h>
 #include <sys/systm.h>
-#include <sys/uio.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
 
 #include <machine/iodev.h>
 
+#include <dev/io/iodev.h>
+
+static int	 ioopen(struct cdev *dev, int flags, int fmt,
+		    struct thread *td);
+static int	 ioclose(struct cdev *dev, int flags, int fmt,
+		    struct thread *td);
+static int	 ioioctl(struct cdev *dev, u_long cmd, caddr_t data,
+		    int fflag, struct thread *td);
+
+static int	 iopio_read(struct iodev_pio_req *req);
+static int	 iopio_write(struct iodev_pio_req *req);
+
 static struct cdev *iodev;
 
 static struct cdevsw io_cdevsw = {
@@ -58,6 +63,129 @@ static struct cdevsw io_cdevsw = {
 
 /* ARGSUSED */
 static int
+ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
+    struct thread *td)
+{
+	int error;
+
+	error = priv_check(td, PRIV_IO);
+	if (error != 0)
+		return (error);
+	error = securelevel_gt(td->td_ucred, 0);
+	if (error != 0)
+		return (error);
+	error = iodev_open(td);
+
+        return (error);
+}
+
+/* ARGSUSED */
+static int
+ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
+    struct thread *td)
+{
+
+	return (iodev_close(td));
+}
+
+/* ARGSUSED */
+static int
+ioioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
+    int fflag __unused, struct thread *td __unused)
+{
+	struct iodev_pio_req *pio_req;
+	int error;
+
+	switch (cmd) {
+	case IODEV_PIO:
+		pio_req = (struct iodev_pio_req *)data;
+		switch (pio_req->access) {
+		case IODEV_PIO_READ:
+			error = iopio_read(pio_req);
+			break;
+		case IODEV_PIO_WRITE:
+			error = iopio_write(pio_req);
+			break;
+		default:
+			error = EINVAL;
+			break;
+		}
+		break;
+	default:
+		error = iodev_ioctl(cmd, data);
+	}
+
+	return (error);
+}
+
+static int
+iopio_read(struct iodev_pio_req *req)
+{
+
+	switch (req->width) {
+	case 1:
+		req->val = iodev_read_1(req->port);
+		break;
+	case 2:
+		if (req->port & 1) {
+			req->val = iodev_read_1(req->port);
+			req->val |= iodev_read_1(req->port + 1) << 8;
+		} else
+			req->val = iodev_read_2(req->port);
+		break;
+	case 4:
+		if (req->port & 1) {
+			req->val = iodev_read_1(req->port);
+			req->val |= iodev_read_2(req->port + 1) << 8;
+			req->val |= iodev_read_1(req->port + 3) << 24;
+		} else if (req->port & 2) {
+			req->val = iodev_read_2(req->port);
+			req->val |= iodev_read_2(req->port + 2) << 16;
+		} else
+			req->val = iodev_read_4(req->port);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static int
+iopio_write(struct iodev_pio_req *req)
+{
+
+	switch (req->width) {
+	case 1:
+		iodev_write_1(req->port, req->val);
+		break;
+	case 2:
+		if (req->port & 1) {
+			iodev_write_1(req->port, req->val);
+			iodev_write_1(req->port + 1, req->val >> 8);
+		} else
+			iodev_write_2(req->port, req->val);
+		break;
+	case 4:
+		if (req->port & 1) {
+			iodev_write_1(req->port, req->val);
+			iodev_write_2(req->port + 1, req->val >> 8);
+			iodev_write_1(req->port + 3, req->val >> 24);
+		} else if (req->port & 2) {
+			iodev_write_2(req->port, req->val);
+			iodev_write_2(req->port + 2, req->val >> 16);
+		} else
+			iodev_write_4(req->port, req->val);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+/* ARGSUSED */
+static int
 io_modevent(module_t mod __unused, int type, void *data __unused)
 {
 	switch(type) {

Added: head/sys/dev/io/iodev.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/io/iodev.h	Wed Apr 28 15:38:01 2010	(r207329)
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2010 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEV_IODEV_H_
+#define	_DEV_IODEV_H_
+
+#define	IODEV_PIO_READ		0
+#define	IODEV_PIO_WRITE		1
+
+struct iodev_pio_req {
+	u_int access;
+	u_int port;
+	u_int width;
+	u_int val;
+};
+
+#define	IODEV_PIO	_IOWR('I', 0, struct iodev_pio_req)
+
+#endif /* _DEV_IODEV_H_ */

Modified: head/sys/i386/i386/io.c
==============================================================================
--- head/sys/i386/i386/io.c	Wed Apr 28 15:15:06 2010	(r207328)
+++ head/sys/i386/i386/io.c	Wed Apr 28 15:38:01 2010	(r207329)
@@ -28,60 +28,32 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/priv.h>
 #include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/systm.h>
 
-#include <machine/db_machdep.h>
 #include <machine/frame.h>
-#include <machine/psl.h>
-#include <machine/specialreg.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
 #include <machine/iodev.h>
+#include <machine/psl.h>
 
-/* ARGSUSED */
 int
-ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
-    struct thread *td)
+iodev_open(struct thread *td)
 {
-	int error;
-
-	error = priv_check(td, PRIV_IO);
-	if (error != 0)
-		return (error);
-	error = securelevel_gt(td->td_ucred, 0);
-	if (error != 0)
-		return (error);
 
 	td->td_frame->tf_eflags |= PSL_IOPL;
-
 	return (0);
 }
 
-/* ARGSUSED */
 int
-ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
-    struct thread *td)
+iodev_close(struct thread *td)
 {
-	td->td_frame->tf_eflags &= ~PSL_IOPL;
 
+	td->td_frame->tf_eflags &= ~PSL_IOPL;
 	return (0);
 }
 
 /* ARGSUSED */
 int
-ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused,
-    int fflag __unused, struct thread *td __unused)
+iodev_ioctl(u_long cmd __unused, caddr_t data __unused)
 {
 
-	return (ENXIO);
+	return (ENOIOCTL);
 }

Modified: head/sys/i386/include/iodev.h
==============================================================================
--- head/sys/i386/include/iodev.h	Wed Apr 28 15:15:06 2010	(r207328)
+++ head/sys/i386/include/iodev.h	Wed Apr 28 15:38:01 2010	(r207329)
@@ -25,7 +25,22 @@
  *
  * $FreeBSD$
  */
+#ifndef _MACHINE_IODEV_H_
+#define	_MACHINE_IODEV_H_
 
-d_open_t	ioopen;
-d_close_t	ioclose;
-d_ioctl_t	ioioctl;
+#ifdef _KERNEL
+#include <machine/cpufunc.h>
+
+#define	iodev_read_1	inb
+#define	iodev_read_2	inw
+#define	iodev_read_4	inl
+#define	iodev_write_1	outb
+#define	iodev_write_2	outw
+#define	iodev_write_4	outl
+
+int	 iodev_open(struct thread *td);
+int	 iodev_close(struct thread *td);
+int	 iodev_ioctl(u_long cmd, caddr_t data);
+
+#endif /* _KERNEL */
+#endif /* _MACHINE_IODEV_H_ */

Modified: head/sys/ia64/ia64/iodev_machdep.c
==============================================================================
--- head/sys/ia64/ia64/iodev_machdep.c	Wed Apr 28 15:15:06 2010	(r207328)
+++ head/sys/ia64/ia64/iodev_machdep.c	Wed Apr 28 15:38:01 2010	(r207329)
@@ -40,61 +40,33 @@ __FBSDID("$FreeBSD$");
 #include <machine/efi.h>
 #include <machine/iodev.h>
 
-static int iodev_pio_read(struct iodev_pio_req *req);
-static int iodev_pio_write(struct iodev_pio_req *req);
-
 static int iodev_efivar_getvar(struct iodev_efivar_req *req);
 static int iodev_efivar_nextname(struct iodev_efivar_req *req);
 static int iodev_efivar_setvar(struct iodev_efivar_req *req);
 
 /* ARGSUSED */
 int
-ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
-    struct thread *td)
+iodev_open(struct thread *td __unused)
 {
-	int error;
-
-	error = priv_check(td, PRIV_IO);
-	if (error == 0)
-		error = securelevel_gt(td->td_ucred, 0);
 
-	return (error);
+	return (0);
 }
 
 /* ARGSUSED */
 int
-ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
-    struct thread *td __unused)
+iodev_close(struct thread *td __unused)
 {
 
 	return (0);
 }
 
-/* ARGSUSED */
 int
-ioioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
-    int fflag __unused, struct thread *td __unused)
+iodev_ioctl(u_long cmd, caddr_t data)
 {
 	struct iodev_efivar_req *efivar_req;
-	struct iodev_pio_req *pio_req;
 	int error;
 
-	error = ENOIOCTL;
 	switch (cmd) {
-	case IODEV_PIO:
-		pio_req = (struct iodev_pio_req *)data;
-		switch (pio_req->access) {
-		case IODEV_PIO_READ:
-			error = iodev_pio_read(pio_req);
-			break;
-		case IODEV_PIO_WRITE:
-			error = iodev_pio_write(pio_req);
-			break;
-		default:
-			error = EINVAL;
-			break;
-		}
-		break;
 	case IODEV_EFIVAR:
 		efivar_req = (struct iodev_efivar_req *)data;
 		efivar_req->result = 0;		/* So it's well-defined */
@@ -113,75 +85,11 @@ ioioctl(struct cdev *dev __unused, u_lon
 			break;
 		}
 		break;
-	}
-
-	return (error);
-}
-
-static int
-iodev_pio_read(struct iodev_pio_req *req)
-{
-
-	switch (req->width) {
-	case 1:
-		req->val = bus_space_read_io_1(req->port);
-		break;
-	case 2:
-		if (req->port & 1) {
-			req->val = bus_space_read_io_1(req->port);
-			req->val |= bus_space_read_io_1(req->port + 1) << 8;
-		} else
-			req->val = bus_space_read_io_2(req->port);
-		break;
-	case 4:
-		if (req->port & 1) {
-			req->val = bus_space_read_io_1(req->port);
-			req->val |= bus_space_read_io_2(req->port + 1) << 8;
-			req->val |= bus_space_read_io_1(req->port + 3) << 24;
-		} else if (req->port & 2) {
-			req->val = bus_space_read_io_2(req->port);
-			req->val |= bus_space_read_io_2(req->port + 2) << 16;
-		} else
-			req->val = bus_space_read_io_4(req->port);
-		break;
-	default:
-		return (EINVAL);
-	}
-
-	return (0);
-}
-
-static int
-iodev_pio_write(struct iodev_pio_req *req)
-{
-
-	switch (req->width) {
-	case 1:
-		bus_space_write_io_1(req->port, req->val);
-		break;
-	case 2:
-		if (req->port & 1) {
-			bus_space_write_io_1(req->port, req->val);
-			bus_space_write_io_1(req->port + 1, req->val >> 8);
-		} else
-			bus_space_write_io_2(req->port, req->val);
-		break;
-	case 4:
-		if (req->port & 1) {
-			bus_space_write_io_1(req->port, req->val);
-			bus_space_write_io_2(req->port + 1, req->val >> 8);
-			bus_space_write_io_1(req->port + 3, req->val >> 24);
-		} else if (req->port & 2) {
-			bus_space_write_io_2(req->port, req->val);
-			bus_space_write_io_2(req->port + 2, req->val >> 16);
-		} else
-			bus_space_write_io_4(req->port, req->val);
-		break;
 	default:
-		return (EINVAL);
+		error = ENOIOCTL;
 	}
 
-	return (0);
+	return (error);
 }
 
 static int

Modified: head/sys/ia64/include/iodev.h
==============================================================================
--- head/sys/ia64/include/iodev.h	Wed Apr 28 15:15:06 2010	(r207328)
+++ head/sys/ia64/include/iodev.h	Wed Apr 28 15:38:01 2010	(r207329)
@@ -31,22 +31,16 @@
 
 #include <sys/uuid.h>
 
-struct iodev_pio_req {
-	u_int access;
-#define	IODEV_PIO_READ		0
-#define	IODEV_PIO_WRITE		1
-	u_int port;
-	u_int width;
-	u_int val;
-};
-
-#define	IODEV_PIO	_IOWR('I', 0, struct iodev_pio_req)
+#ifdef _KERNEL
+#include <machine/bus.h>
+#endif
 
-struct iodev_efivar_req {
-	u_int	access;
 #define	IODEV_EFIVAR_GETVAR	0
 #define	IODEV_EFIVAR_NEXTNAME	1
 #define	IODEV_EFIVAR_SETVAR	2
+
+struct iodev_efivar_req {
+	u_int	access;
 	u_int	result;			/* errno value */
 	size_t	namesize;
 	u_short	*name;			/* UCS-2 */
@@ -59,11 +53,16 @@ struct iodev_efivar_req {
 #define	IODEV_EFIVAR	_IOWR('I', 1, struct iodev_efivar_req)
 
 #ifdef _KERNEL
+#define	iodev_read_1	bus_space_read_io_1
+#define	iodev_read_2	bus_space_read_io_2
+#define	iodev_read_4	bus_space_read_io_4
+#define	iodev_write_1	bus_space_write_io_1
+#define	iodev_write_2	bus_space_write_io_2
+#define	iodev_write_4	bus_space_write_io_4
+
+int	 iodev_open(struct thread *td);
+int	 iodev_close(struct thread *td);
+int	 iodev_ioctl(u_long, caddr_t data);
 
-d_open_t	ioopen;
-d_close_t	ioclose;
-d_ioctl_t	ioioctl;
-
-#endif
-
+#endif /* _KERNEL */
 #endif /* _MACHINE_IODEV_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 4 Eitan Adler freebsd_committer freebsd_triage 2011-03-01 15:15:12 UTC
State Changed
From-To: open->patched

committed in head
Comment 5 Eitan Adler freebsd_committer freebsd_triage 2011-03-01 15:22:54 UTC
Responsible Changed
From-To: freebsd-threads->attilio

same as above
Comment 6 Eitan Adler freebsd_committer freebsd_triage 2013-03-15 23:41:56 UTC
State Changed
From-To: patched->closed

MFCed/fixed by now or it will never be MFCed