diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-04-28 13:25:04 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-04-28 13:25:04 +0000 |
commit | 0ad8269b3581fe97df806943a4d2c28182dc10bd (patch) | |
tree | 438156b7e9d4df07c62669de56ba41867459aaab /xenolinux-2.4.21-pre4-sparse | |
parent | dc52205a054324ff2c40ba5c0c460806cdb98856 (diff) | |
parent | a8155b307121742a75fa17058ab69161c649989f (diff) | |
download | xen-0ad8269b3581fe97df806943a4d2c28182dc10bd.tar.gz xen-0ad8269b3581fe97df806943a4d2c28182dc10bd.tar.bz2 xen-0ad8269b3581fe97df806943a4d2c28182dc10bd.zip |
bitkeeper revision 1.184.1.7 (3ead2bb0z-Au3xm19OXW9JIFLwKvPw)
Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xeno
Diffstat (limited to 'xenolinux-2.4.21-pre4-sparse')
3 files changed, 37 insertions, 5 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; } diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/process.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/process.c index d4db667474..a7c0755d38 100644 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/process.c +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/process.c @@ -363,7 +363,12 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p) } if ( next->esp0 != 0 ) + { queue_multicall2(__HYPERVISOR_stack_switch, __KERNEL_DS, next->esp0); + /* Next call will silently fail if we are a non-privileged guest OS. */ + queue_multicall1(__HYPERVISOR_iopl, + ((((struct pt_regs *)next->esp0)-1)->eflags>>12)&3); + } /* EXECUTE ALL TASK SWITCH XEN SYSCALLS AT THIS POINT. */ execute_multicall_list(); diff --git a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h index 47e2965fe0..887a01b231 100644 --- a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h +++ b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h @@ -353,7 +353,6 @@ static inline int HYPERVISOR_multicall(void *call_list, int nr_calls) return ret; } - static inline long HYPERVISOR_kbd_op(unsigned char op, unsigned char val) { int ret; @@ -365,4 +364,15 @@ static inline long HYPERVISOR_kbd_op(unsigned char op, unsigned char val) return ret; } +static inline long HYPERVISOR_iopl(unsigned int new_iopl) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_iopl), + "b" (new_iopl) ); + + return ret; +} + #endif /* __HYPERVISOR_H__ */ |