Regarding User Space access of IO ports

Warner Losh imp at bsdimp.com
Mon Oct 12 14:52:34 UTC 2015


On Mon, Oct 12, 2015 at 5:45 AM, Venkateswara Rao Dokku <dvrao.584 at gmail.com
> wrote:

> Hi,
>
> I am trying to access the IO ports from user space. This I am doing by
> having an ioctl that will return the address of the IO port & I am using
> this IO port address returned from kernel, in user space application to
> write to that port via outw();
>
> In short, I did this
>
> 1. Give IOCTL to kernel which will return the IO port address
> 2. FD = open("/dev/io",O_RDWR) in my user space app, this will give the
> privilege to user space to write to the IO address
> 3. outw( ioport_addr+ offset, value)
>
> The question here is, how the outw() work? Does it write to the address
> directly as in kernel  mode or will it give an ioctl on the FD which will
> result in kernel switch?
>

The bit in the CPU that allows I/O port access is set when the process
returns
from kernel mode.

/dev/io is implemented in sys/dev/io. ioopen() does some securitychecks and
then calls iodev_open, which lives in the i386 specific code. It does this
rather
simple looking thing:

        td->td_frame->tf_eflags |= PSL_IOPL;

which sets the IOPL bit in eflags. IOPL is the bit that controls access to
I/O

ports on the Intel architecture. The non-obvious bit here that you need to

know is that on return to usermode, the PSL is loaded with tf_eflags which

normally has this bit clear. td is the thread that opens /dev/io. Code for

amd64 is similar.


There's no ioctl to do this writing, so the /dev/io driver does do anything

other than have this side effect in the process' PSL. This is a bit odd,

but it's how it works.


Warner


More information about the freebsd-drivers mailing list