aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-05-12 09:11:22 +0000
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-05-12 09:11:22 +0000
commit303ca01553d72c480448a085c62854bc3ec1d4d5 (patch)
tree405aacab05cd87d75e19ac982fa7c49b767d2041 /xen
parent68f817997c9fc419a76d4c9677e663e63d487e22 (diff)
downloadxen-303ca01553d72c480448a085c62854bc3ec1d4d5.tar.gz
xen-303ca01553d72c480448a085c62854bc3ec1d4d5.tar.bz2
xen-303ca01553d72c480448a085c62854bc3ec1d4d5.zip
bitkeeper revision 1.899 (40a1ea3a_7ZmXmUq-RTnUSd3QZ_X1Q)
live migration cleanups
Diffstat (limited to 'xen')
-rw-r--r--xen/Rules.mk5
-rw-r--r--xen/common/dom0_ops.c12
-rw-r--r--xen/common/kernel.c3
-rw-r--r--xen/common/shadow.c131
-rw-r--r--xen/include/hypervisor-ifs/dom0_ops.h1
-rw-r--r--xen/include/xen/shadow.h1
6 files changed, 110 insertions, 43 deletions
diff --git a/xen/Rules.mk b/xen/Rules.mk
index a9db6358a4..e75a79cbe2 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -3,6 +3,7 @@ TARGET_ARCH ?= $(COMPILE_ARCH)
nodev ?= n
debug ?= n
+trace ?= n
TARGET := $(BASEDIR)/xen
HDRS := $(wildcard $(BASEDIR)/include/xen/*.h)
@@ -50,6 +51,10 @@ ifeq ($(nodev),y)
CFLAGS += -DNO_DEVICES_IN_XEN
endif
+ifeq ($(trace),y)
+CFLAGS += -DTRACE_BUFFER
+endif
+
%.o: %.c $(HDRS) Makefile
$(CC) $(CFLAGS) -c $< -o $@
diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
index dee7552bdd..f768edd5ff 100644
--- a/xen/common/dom0_ops.c
+++ b/xen/common/dom0_ops.c
@@ -21,6 +21,11 @@
#include <xen/shadow.h>
#include <hypervisor-ifs/sched_ctl.h>
+
+#define TRC_DOM0OP_START_BASE 0x00020000
+#define TRC_DOM0OP_FINISH_BASE 0x00030000
+
+
extern unsigned int alloc_new_dom_mem(struct task_struct *, unsigned int);
/* Basically used to protect the domain-id space. */
@@ -68,6 +73,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
return -EACCES;
}
+ TRACE_5D( TRC_DOM0OP_START_BASE + op->cmd,
+ 0, op->u.dummy[0], op->u.dummy[1], op->u.dummy[2], op->u.dummy[3] );
+
switch ( op->cmd )
{
@@ -671,5 +679,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
}
+ TRACE_5D( TRC_DOM0OP_FINISH_BASE + op->cmd, ret,
+ op->u.dummy[0], op->u.dummy[1], op->u.dummy[2], op->u.dummy[3] );
+
+
return ret;
}
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 0d5fa023a1..b33524928d 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -31,6 +31,7 @@
#include <xen/console.h>
#include <xen/net_headers.h>
#include <xen/serial.h>
+#include <xen/shadow.h>
kmem_cache_t *task_struct_cachep;
@@ -268,6 +269,8 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
set_bit(PF_PRIVILEGED, &new_dom->flags);
+ shadow_mode_init();
+
/*
* We're going to setup domain0 using the module(s) that we stashed safely
* above our MAX_DIRECTMAP_ADDRESS in boot/boot.S. The second module, if
diff --git a/xen/common/shadow.c b/xen/common/shadow.c
index fe142e3ee9..ec5ce29d5a 100644
--- a/xen/common/shadow.c
+++ b/xen/common/shadow.c
@@ -6,6 +6,8 @@
#include <xen/shadow.h>
#include <asm/domain_page.h>
#include <asm/page.h>
+#include <xen/event.h>
+#include <xen/trace.h>
/********
@@ -26,6 +28,8 @@ hypercall lock anyhow (at least initially).
********/
+static spinlock_t cpu_stall_lock;
+
static inline void free_shadow_page( struct mm_struct *m,
struct pfn_info *pfn_info )
{
@@ -155,6 +159,11 @@ static void __scan_shadow_table( struct mm_struct *m, unsigned int op )
}
+void shadow_mode_init(void)
+{
+ spin_lock_init( &cpu_stall_lock );
+}
+
int shadow_mode_enable( struct task_struct *p, unsigned int mode )
{
struct mm_struct *m = &p->mm;
@@ -260,11 +269,11 @@ void shadow_mode_disable( struct task_struct *p )
}
static int shadow_mode_table_op( struct task_struct *p,
- dom0_shadow_control_t *sc )
+ dom0_shadow_control_t *sc )
{
- unsigned int op = sc->op;
+ unsigned int op = sc->op;
struct mm_struct *m = &p->mm;
- int rc = 0;
+ int rc = 0;
// since Dom0 did the hypercall, we should be running with it's page
// tables right now. Calling flush on yourself would be really
@@ -290,37 +299,50 @@ static int shadow_mode_table_op( struct task_struct *p,
break;
case DOM0_SHADOW_CONTROL_OP_CLEAN:
+ {
+ int i,j,zero=1;
+
+ __scan_shadow_table( m, op );
+
+ if( p->tot_pages > sc->pages ||
+ !sc->dirty_bitmap || !p->mm.shadow_dirty_bitmap )
{
- int i;
-
- __scan_shadow_table( m, op );
-
- if( p->tot_pages > sc->pages ||
- !sc->dirty_bitmap || !p->mm.shadow_dirty_bitmap )
- {
- rc = -EINVAL;
- goto out;
- }
-
- sc->pages = p->tot_pages;
-
+ rc = -EINVAL;
+ goto out;
+ }
+
+ sc->pages = p->tot_pages;
+
#define chunk (8*1024) // do this in 1KB chunks for L1 cache
-
- for(i=0;i<p->tot_pages;i+=chunk)
+
+ for(i=0;i<p->tot_pages;i+=chunk)
+ {
+ int bytes = (( ((p->tot_pages-i) > (chunk))?
+ (chunk):(p->tot_pages-i) ) + 7) / 8;
+
+ copy_to_user( sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
+ p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
+ bytes );
+
+ for(j=0; zero && j<bytes/sizeof(unsigned long);j++)
{
- int bytes = (( ((p->tot_pages-i) > (chunk))?
- (chunk):(p->tot_pages-i) ) + 7) / 8;
-
- copy_to_user( sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
- p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
- bytes );
+ if( p->mm.shadow_dirty_bitmap[j] != 0 )
+ zero = 0;
+ }
- memset( p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
- 0, bytes);
- }
+ memset( p->mm.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
+ 0, bytes);
+ }
- break;
+ if (zero)
+ {
+ /* might as well stop the domain as an optimization. */
+ if ( p->state != TASK_STOPPED )
+ send_guest_virq(p, VIRQ_STOP);
}
+
+ break;
+ }
}
@@ -338,22 +360,45 @@ out:
return rc;
}
-
int shadow_mode_control( struct task_struct *p, dom0_shadow_control_t *sc )
{
- int we_paused = 0;
- unsigned int cmd = sc->op;
- int rc = 0;
-
+ unsigned int cmd = sc->op;
+ int rc = 0, cpu;
+
// don't call if already shadowed...
- // sychronously stop domain
- if( 0 && !(p->state & TASK_STOPPED) && !(p->state & TASK_PAUSED))
- {
- printk("about to pause domain\n");
- sched_pause_sync(p);
- printk("paused domain\n");
- we_paused = 1;
+ /* The following is pretty hideous because we don't have a way of
+ synchronously pausing a domain. If it's assigned to the curernt CPU,
+ we don't have to worry -- it can't possibly actually be running.
+ If its on another CPU, for the moment, we do something really gross:
+ we cause the other CPU to spin regardless of what domain it is running.
+
+ I know this is really grim, but it only lasts a few 10's of
+ microseconds. It needs fixing as soon as the last of the Linux-isms
+ get removed from the task structure...
+
+ Oh, and let's hope someone doesn't repin the CPU while we're here.
+ Also, prey someone else doesn't do this in another domain.
+ At least there's only one dom0 at the moment...
+ */
+printk("SMC\n");
+ spin_lock( &cpu_stall_lock );
+ cpu = p->processor;
+printk("got %d %d\n",cpu, current->processor );
+ if ( cpu != current->processor )
+ {
+printk("CPU %d %d\n",cpu, current->processor );
+ static void cpu_stall(void * data)
+ {
+ if ( current->processor == (int) data )
+ {
+ printk("Stall %d\n",(int)data);
+ spin_lock( &cpu_stall_lock );
+ spin_unlock( &cpu_stall_lock );
+ }
+ }
+
+ smp_call_function(cpu_stall, (void*)cpu, 1, 0); // don't wait!
}
if ( p->mm.shadow_mode && cmd == DOM0_SHADOW_CONTROL_OP_OFF )
@@ -376,11 +421,11 @@ int shadow_mode_control( struct task_struct *p, dom0_shadow_control_t *sc )
}
else
{
- if ( we_paused ) wake_up(p);
- return -EINVAL;
+ rc = -EINVAL;
}
- if ( we_paused ) wake_up(p);
+ spin_unlock( &cpu_stall_lock );
+printk("SMC-\n");
return rc;
}
diff --git a/xen/include/hypervisor-ifs/dom0_ops.h b/xen/include/hypervisor-ifs/dom0_ops.h
index 0027e9df29..879a728bd4 100644
--- a/xen/include/hypervisor-ifs/dom0_ops.h
+++ b/xen/include/hypervisor-ifs/dom0_ops.h
@@ -289,6 +289,7 @@ typedef struct dom0_op_st
unsigned long interface_version; /* DOM0_INTERFACE_VERSION */
union
{
+ unsigned long dummy[4];
dom0_createdomain_t createdomain;
dom0_startdomain_t startdomain;
dom0_stopdomain_t stopdomain;
diff --git a/xen/include/xen/shadow.h b/xen/include/xen/shadow.h
index 01b46301aa..bfb2a04256 100644
--- a/xen/include/xen/shadow.h
+++ b/xen/include/xen/shadow.h
@@ -23,6 +23,7 @@
#define shadow_linear_pg_table ((l1_pgentry_t *)SH_LINEAR_PT_VIRT_START)
#define shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START+(SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
+extern void shadow_mode_init(void);
extern int shadow_mode_control( struct task_struct *p, dom0_shadow_control_t *sc );
extern int shadow_fault( unsigned long va, long error_code );
extern void shadow_l1_normal_pt_update( unsigned long pa, unsigned long gpte,