diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-04-28 15:11:10 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-04-28 15:11:10 +0000 |
commit | 21da7264398416838c428c5d6ad0d3db74ba661e (patch) | |
tree | 96a17e36dd62ac98ae27389e24e36c0911e573cd | |
parent | a0ed4d10510c34453708f7322e1a4ef08b826b2d (diff) | |
parent | 0ad8269b3581fe97df806943a4d2c28182dc10bd (diff) | |
download | xen-21da7264398416838c428c5d6ad0d3db74ba661e.tar.gz xen-21da7264398416838c428c5d6ad0d3db74ba661e.tar.bz2 xen-21da7264398416838c428c5d6ad0d3db74ba661e.zip |
bitkeeper revision 1.191 (3ead448eiWx9DnIJDafKeaW69PFN8g)
Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/ach-xeno
-rw-r--r-- | xen/arch/i386/entry.S | 1 | ||||
-rw-r--r-- | xen/arch/i386/process.c | 16 | ||||
-rw-r--r-- | xen/common/domain.c | 6 | ||||
-rw-r--r-- | xen/include/hypervisor-ifs/hypervisor-if.h | 6 | ||||
-rw-r--r-- | xen/include/xeno/sched.h | 9 | ||||
-rw-r--r-- | xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c | 25 | ||||
-rw-r--r-- | xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/process.c | 5 | ||||
-rw-r--r-- | xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h | 14 | ||||
-rwxr-xr-x | xenolinux-2.4.21-pre4-sparse/mkbuildtree | 1 |
9 files changed, 69 insertions, 14 deletions
diff --git a/xen/arch/i386/entry.S b/xen/arch/i386/entry.S index afb4a5c54c..f14f594ee5 100644 --- a/xen/arch/i386/entry.S +++ b/xen/arch/i386/entry.S @@ -647,6 +647,7 @@ ENTRY(hypervisor_call_table) .long SYMBOL_NAME(do_dom_mem_op) .long SYMBOL_NAME(do_multicall) .long SYMBOL_NAME(do_kbd_op) + .long SYMBOL_NAME(do_iopl) .rept NR_syscalls-((.-hypervisor_call_table)/4) .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/xen/arch/i386/process.c b/xen/arch/i386/process.c index 85f438f4fa..2cac1a9d4e 100644 --- a/xen/arch/i386/process.c +++ b/xen/arch/i386/process.c @@ -31,6 +31,9 @@ #include <xeno/irq.h> #include <xeno/event.h> +#define GET_SYSCALL_REGS(_p) \ + (((struct pt_regs *)(THREAD_SIZE + (unsigned long)(_p))) - 1) + asmlinkage void ret_from_newdomain(void) __asm__("ret_from_newdomain"); int hlt_counter; @@ -247,9 +250,7 @@ void new_thread(struct task_struct *p, unsigned long start_stack, unsigned long start_info) { - struct pt_regs * regs; - - regs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1; + struct pt_regs *regs = GET_SYSCALL_REGS(p); memset(regs, 0, sizeof(*regs)); /* @@ -345,3 +346,12 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p) } } + + +long do_iopl(unsigned int new_iopl) +{ + struct pt_regs *regs = GET_SYSCALL_REGS(current); + if ( !IS_PRIV(current) ) return -EPERM; + regs->eflags = (regs->eflags & 0xffffcfff) | ((new_iopl&3) << 12); + return 0; +} diff --git a/xen/common/domain.c b/xen/common/domain.c index 1f3a2dd406..349acc5b57 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -357,6 +357,9 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo) virt_startinfo_addr->mod_start = meminfo->virt_mod_addr; virt_startinfo_addr->mod_len = meminfo->virt_mod_len; + virt_startinfo_addr->dom_id = p->domain; + virt_startinfo_addr->flags = IS_PRIV(p) ? SIF_PRIVILEGED : 0; + if( virt_startinfo_addr->mod_len ) printk("Initrd module present %08lx (%08lx)\n", virt_startinfo_addr->mod_start, @@ -618,6 +621,9 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params, virt_startinfo_address->pt_base = virt_load_address + ((p->tot_pages - 1) << PAGE_SHIFT); + virt_startinfo_address->dom_id = p->domain; + virt_startinfo_address->flags = IS_PRIV(p) ? SIF_PRIVILEGED : 0; + if ( initrd_len ) { virt_startinfo_address->mod_start = (unsigned long)dst-initrd_len; diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index 7e5499aad7..6b74f92b66 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -48,6 +48,7 @@ #define __HYPERVISOR_dom_mem_op 17 #define __HYPERVISOR_multicall 18 #define __HYPERVISOR_kbd_op 19 +#define __HYPERVISOR_iopl 20 /* And the trap vector is... */ #define TRAP_INSTR "int $0x82" @@ -242,9 +243,14 @@ typedef struct start_info_st { unsigned long net_rings[MAX_DOMAIN_VIFS]; /* Machine address of block-device ring. Will be page aligned. */ unsigned long blk_ring; + unsigned int dom_id; + unsigned long flags; unsigned char cmd_line[1]; /* variable-length */ } start_info_t; +/* These flags are passed in the 'flags' field of start_info_t. */ +#define SIF_PRIVILEGED 1 /* Is thie domain privileged? */ + /* For use in guest OSes. */ extern shared_info_t *HYPERVISOR_shared_info; diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h index 11a8d14b7c..d29c7f9e49 100644 --- a/xen/include/xeno/sched.h +++ b/xen/include/xeno/sched.h @@ -60,8 +60,11 @@ extern struct mm_struct init_mm; #include <xeno/block.h> #include <xeno/segment.h> -struct task_struct { +/* SMH: replace below when have explicit 'priv' flag or bitmask */ +#define IS_PRIV(_p) ((_p)->domain == 0) +struct task_struct +{ /* * DO NOT CHANGE THE ORDER OF THE FOLLOWING. * Their offsets are hardcoded in entry.S @@ -72,10 +75,6 @@ struct task_struct { int hyp_events; /* 08: pending intra-Xen events */ unsigned int domain; /* 12: domain id */ - // SMH: replace below when have explicit 'priv' flag or bitmask -#define IS_PRIV(_p) ((_p)->domain == 0) - - /* An unsafe pointer into a shared data area. */ shared_info_t *shared_info; /* 16: shared data area */ 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 935ea3a6ef..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 @@ -11,7 +11,7 @@ #include <asm/hypervisor-ifs/hypervisor-if.h> #include <asm/ptrace.h> -#include <asm/page.h> +//#include <asm/page.h> /* arch/xeno/kernel/setup.c */ union start_info_union @@ -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__ */ diff --git a/xenolinux-2.4.21-pre4-sparse/mkbuildtree b/xenolinux-2.4.21-pre4-sparse/mkbuildtree index 8749150889..38f76d7e2b 100755 --- a/xenolinux-2.4.21-pre4-sparse/mkbuildtree +++ b/xenolinux-2.4.21-pre4-sparse/mkbuildtree @@ -23,6 +23,7 @@ rm -f ${D}/mkbuildtree ## subdirectories. # This first symlink is special: it links to shared files in Xen's source tree +rm -f ${D}/include/asm-xeno/hypervisor-ifs ln -sf `pwd`/../xen/include/hypervisor-ifs ${D}/include/asm-xeno/hypervisor-ifs # The remainder are the i386 -> xeno-i386 links |