Mailing List Archive

Trying to run X in domain 1: Failed to do IOPL (was Re:USB with Xen 2.0)
> I guess the X server might try doing IO to some things that Xen won't let
> it access. By default, the domain will only have access to the IO ports
> and IO memory regions of the graphics card and USB controller themselves.

As reported earlier, I'm receiving an 'Failed to do IOPL' message when
starting X in domain 1. It seems to be also triggered when running scanpci
in the same domain, or in domain 0 as non-root user.

So I untarred myself the X sources (it is sometimes handy to have a gentoo
distro installed :-), and started to look for the mentioned error.
I found the following code, which seems to trigger the problem:

if (ioperm(0, 1024, 1) || iopl(3))
FatalError("xf86EnableIOPorts: Failed to set IOPL for I/O\n");

Since I have no clue what ioperm or iopl do, I looked up the man pages,
and found this:

int ioperm(unsigned long from, unsigned long num, int turn_on);

Ioperm sets the port access permission bits for the process for num bytes
starting from port address from to the value turn_on. The use of ioperm
requires root privileges.
Only the first 0x3ff I/O ports can be specified in this manner. For more
ports, the iopl function must be used. Permissions are not inherited on fork,
but on exec they are. This is useful for giving port access permissions to
non-privileged tasks.


int iopl(int level);

iopl changes the I/O privilege level of the current process, as specified in
level.
This call is necessary to allow 8514-compatible X servers to run under Linux.
Since these X servers require access to all 65536 I/O ports, the ioperm call
is not sufficient.
In addition to granting unrestricted I/O port access, running at a higher I/O
privilege level also allows the process to disable interrupts. This will
probably crash the system, and is not recommended.


Although I don't want X to touch hardware in other domains, it is ok for me if
it touches any hardware which I assigned to domain 1.

Why are these calls not working? Does Xen need to intercept these calls
to keep things working? Can I do anything to get passed this problem?


Best Regards,
Mark


-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xen-devel
Re: Trying to run X in domain 1: Failed to do IOPL (was Re:USB with Xen 2.0) [ In reply to ]
On Thursday 21 October 2004 22:28, Mark Hurenkamp wrote:
> > I guess the X server might try doing IO to some things that Xen won't let
> > it access. By default, the domain will only have access to the IO ports
> > and IO memory regions of the graphics card and USB controller themselves.
>
> As reported earlier, I'm receiving an 'Failed to do IOPL' message when
> starting X in domain 1. It seems to be also triggered when running scanpci
> in the same domain, or in domain 0 as non-root user.
>
> So I untarred myself the X sources (it is sometimes handy to have a gentoo
> distro installed :-), and started to look for the mentioned error.
> I found the following code, which seems to trigger the problem:
>
> if (ioperm(0, 1024, 1) || iopl(3))
> FatalError("xf86EnableIOPorts: Failed to set IOPL for
> I/O\n");
>

If you're feeling brave, as a quick and very dirty hack you could comment out
lines 98 and 99 of xen/common/dom0_ops.c - i.e. these ones:

if ( !IS_PRIV(current) )
return -EPERM;

Do read on for an explanation of what this will do, before trying it ;-)

> Although I don't want X to touch hardware in other domains, it is ok for me
> if it touches any hardware which I assigned to domain 1.
>
> Why are these calls not working? Does Xen need to intercept these calls
> to keep things working? Can I do anything to get passed this problem?

When a userspace process does an iopl or ioperm call, the XenLinux kernel does
an iopl call into Xen (that's not a typo, there's no ioperm hypercall). Xen
checks whether the domain is privileged enough to be trusted with a higher IO
privileges level and only allows the call to succeed if it is.

Domains which have PCI access don't need to do an IOPL call because they are
(implicitly) given access to their IO ports they need. They're therefore not
given privileges to do it. Unfortunately, it seems that X wants to do this
anyhow.

Commenting out those lines will allow any domain to do an IOPL call (amongst
other things). This should keep X happy. I'm not sure exactly what X will
try and access - if it tries to poke about in the BIOS or in hardware that
dom0 is using, bad things may happen. If it were my system (and in the
absence of other suggestions), I'd cross my fingers and give it a shot.

Obviously, allowing all domains to make privileged calls is not ideal ;-) If
X really only does need to access IO ports of its PCI device, we can tighten
this up trivially by adding better support for the ioperm call. I'll
implement this if it looks like it'll work.

HTH,
Mark


-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xen-devel
Re: Re: Trying to run X in domain 1: Failed to do IOPL (was Re:USB with Xen 2.0) [ In reply to ]
> > So I untarred myself the X sources (it is sometimes handy to have a gentoo
> > distro installed :-), and started to look for the mentioned error.
> > I found the following code, which seems to trigger the problem:
> >
> > if (ioperm(0, 1024, 1) || iopl(3))
> > FatalError("xf86EnableIOPorts: Failed to set IOPL for
> > I/O\n");

> Obviously, allowing all domains to make privileged calls is not ideal ;-) If
> X really only does need to access IO ports of its PCI device, we can tighten
> this up trivially by adding better support for the ioperm call. I'll
> implement this if it looks like it'll work.

Unfortunately the code looks wrong to me --- it requires *both* the
ioperm() and the iopl() call to succeed. Even if you tighten up
ioperm, only a privileged domain can do iopl. So it looks like X
server domains will have to be privileged.

I also hadn't considered that, in giving a domain selective I/O port
access, we are actually giving everything that runs in that domain
that access (i.e., all random user space programs, because we do not
change the bitmap on process switches, or user/kernel transitions).
Of course our intention is that usually such a domain won't have a
fully-fledged user space so I guess we don't really care that much.
It can also only affect the device that domian controls, and we can
detect and restart on failure. :-)

-- Keir


-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xen-devel
Re: Re: Trying to run X in domain 1: Failed to do IOPL (was Re:USB with Xen 2.0) [ In reply to ]
>> > So I untarred myself the X sources (it is sometimes handy to have a gentoo
>> > distro installed :-), and started to look for the mentioned error.
>> > I found the following code, which seems to trigger the problem:
>> >
>> > if (ioperm(0, 1024, 1) || iopl(3))
>> > FatalError("xf86EnableIOPorts: Failed to set IOPL for
>> > I/O\n");
>
>> Obviously, allowing all domains to make privileged calls is not ideal ;-) I
f
>> X really only does need to access IO ports of its PCI device, we can tighten

>> this up trivially by adding better support for the ioperm call. I'll
>> implement this if it looks like it'll work.
>
>Unfortunately the code looks wrong to me --- it requires *both* the
>ioperm() and the iopl() call to succeed. Even if you tighten up
>ioperm, only a privileged domain can do iopl. So it looks like X
>server domains will have to be privileged.

Hmm -- does X really need iopl() in all cases? The iopl() man page
seems to suggest it does, but perhaps worth tracing the X server's
accesses under linux to check. If it only needs a (perhaps slightly
larger) port range, then we can make the iopl(3) 'succeed' for
unpriv domains by being equivalent to ioperm(0, 1024, 1).

Pretty cheesy though :-)

cheers,

S.