aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-28 15:11:10 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-28 15:11:10 +0000
commit21da7264398416838c428c5d6ad0d3db74ba661e (patch)
tree96a17e36dd62ac98ae27389e24e36c0911e573cd
parenta0ed4d10510c34453708f7322e1a4ef08b826b2d (diff)
parent0ad8269b3581fe97df806943a4d2c28182dc10bd (diff)
downloadxen-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.S1
-rw-r--r--xen/arch/i386/process.c16
-rw-r--r--xen/common/domain.c6
-rw-r--r--xen/include/hypervisor-ifs/hypervisor-if.h6
-rw-r--r--xen/include/xeno/sched.h9
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c25
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/process.c5
-rw-r--r--xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h14
-rwxr-xr-xxenolinux-2.4.21-pre4-sparse/mkbuildtree1
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