aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c
diff options
context:
space:
mode:
Diffstat (limited to 'xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c')
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c
index 798c5c5c1f..c43daee3fd 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c
@@ -7,13 +7,30 @@
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
- /* No IO permission! */
- return -EPERM;
+ /* No IO permission! Selective IO perms aren't virtualised yet. */
+ return -EPERM;
}
asmlinkage int sys_iopl(unsigned long unused)
{
- /* The hypervisor won't allow it! */
- return -EPERM;
+ struct pt_regs *regs = (struct pt_regs *)&unused;
+ unsigned int level = regs->ebx;
+ unsigned int old = (regs->eflags >> 12) & 3;
+
+ if ( !(start_info.flags & SIF_PRIVILEGED) )
+ return -EPERM;
+
+ if ( level > 3 )
+ return -EINVAL;
+ if ( (level > old) && !capable(CAP_SYS_RAWIO) )
+ return -EPERM;
+
+ /* Change the one on our stack for sanity's sake. */
+ regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
+
+ /* Force the change at ring 0. */
+ HYPERVISOR_iopl(level);
+
+ return 0;
}