debuggers.hg
changeset 920:bb30fa014b9d
bitkeeper revision 1.553 (3fa68dcd5yXksUZ7k12Hq41k_eQIOw)
Many files:
More cleanups for suspend/resume. STOP requests are now routed thru the guestos to allow preparation for pickling.
Many files:
More cleanups for suspend/resume. STOP requests are now routed thru the guestos to allow preparation for pickling.
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Mon Nov 03 17:18:05 2003 +0000 (2003-11-03) |
parents | e6d36e3e7847 |
children | 6cde5e25c56f |
files | tools/internal/xi_build.c tools/internal/xi_list.c xen/arch/i386/process.c xen/common/debug.c xen/common/dom0_ops.c xen/common/domain.c xen/common/event.c xen/common/schedule.c xen/include/asm-i386/processor.h xen/include/asm-i386/system.h xen/include/hypervisor-ifs/dom0_ops.h xen/include/hypervisor-ifs/hypervisor-if.h xen/include/xeno/sched.h xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h |
line diff
1.1 --- a/tools/internal/xi_build.c Mon Nov 03 15:16:47 2003 +0000 1.2 +++ b/tools/internal/xi_build.c Mon Nov 03 17:18:05 2003 +0000 1.3 @@ -147,7 +147,8 @@ static int copy_to_domain_page(unsigned 1.4 static int setup_guestos( 1.5 int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages, 1.6 unsigned long virt_load_addr, size_t ksize, 1.7 - dom0_builddomain_t *builddomain, int argc, char **argv, int args_start) 1.8 + dom0_builddomain_t *builddomain, int argc, char **argv, int args_start, 1.9 + unsigned long shared_info_frame) 1.10 { 1.11 l1_pgentry_t *vl1tab = NULL, *vl1e = NULL; 1.12 l2_pgentry_t *vl2tab = NULL, *vl2e = NULL; 1.13 @@ -160,6 +161,7 @@ static int setup_guestos( 1.14 unsigned long count, pt_start, i, j; 1.15 unsigned long initrd_addr = 0, initrd_len = 0; 1.16 start_info_t *start_info; 1.17 + shared_info_t *shared_info; 1.18 int cmd_len; 1.19 1.20 memset(builddomain, 0, sizeof(*builddomain)); 1.21 @@ -319,6 +321,10 @@ static int setup_guestos( 1.22 start_info->pt_base = virt_load_addr + ((tot_pages-1) << PAGE_SHIFT); 1.23 start_info->mod_start = initrd_addr; 1.24 start_info->mod_len = initrd_len; 1.25 + start_info->nr_pages = tot_pages; 1.26 + start_info->shared_info = shared_info_frame << PAGE_SHIFT; 1.27 + start_info->dom_id = dom; 1.28 + start_info->flags = 0; 1.29 cmd_len = 0; 1.30 for ( i = args_start; i < argc; i++ ) 1.31 { 1.32 @@ -333,6 +339,11 @@ static int setup_guestos( 1.33 } 1.34 unmap_pfn(start_info); 1.35 1.36 + /* shared_info page starts its life empty. */ 1.37 + shared_info = map_pfn(shared_info_frame); 1.38 + memset(shared_info, 0, PAGE_SIZE); 1.39 + unmap_pfn(shared_info); 1.40 + 1.41 /* Send the page update requests down to the hypervisor. */ 1.42 if ( send_pgupdates(pgt_update_arr, num_pgt_updates) < 0 ) 1.43 goto error_out; 1.44 @@ -356,7 +367,7 @@ int main(int argc, char **argv) 1.45 * the 8-byte signature and 4-byte load address. 1.46 */ 1.47 size_t ksize; 1.48 - dom0_op_t launch_op; 1.49 + dom0_op_t launch_op, op; 1.50 unsigned long load_addr; 1.51 long tot_pages; 1.52 int kernel_fd, initrd_fd = -1; 1.53 @@ -418,9 +429,24 @@ int main(int argc, char **argv) 1.54 } 1.55 } 1.56 1.57 + op.cmd = DOM0_GETDOMAININFO; 1.58 + op.u.getdomaininfo.domain = domain_id; 1.59 + if ( (do_dom0_op(&op) < 0) || (op.u.getdomaininfo.domain != domain_id) ) 1.60 + { 1.61 + PERROR("Could not get info on domain"); 1.62 + return 1; 1.63 + } 1.64 + if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) || 1.65 + (op.u.getdomaininfo.ctxt.pt_base != 0) ) 1.66 + { 1.67 + ERROR("Domain is already constructed"); 1.68 + return 1; 1.69 + } 1.70 + 1.71 if ( setup_guestos(domain_id, kernel_fd, initrd_fd, tot_pages, 1.72 load_addr, ksize, &launch_op.u.builddomain, 1.73 - argc, argv, args_start) < 0 ) 1.74 + argc, argv, args_start, 1.75 + op.u.getdomaininfo.shared_info_frame) < 0 ) 1.76 return 1; 1.77 1.78 if ( initrd_fd >= 0 ) 1.79 @@ -429,6 +455,8 @@ int main(int argc, char **argv) 1.80 1.81 ctxt = &launch_op.u.builddomain.ctxt; 1.82 1.83 + ctxt->flags = 0; 1.84 + 1.85 /* 1.86 * Initial register values: 1.87 * DS,ES,FS,GS = FLAT_RING1_DS 1.88 @@ -473,8 +501,11 @@ int main(int argc, char **argv) 1.89 /* No debugging. */ 1.90 memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg)); 1.91 1.92 - /* Domain time counts from zero. */ 1.93 - ctxt->domain_time = 0; 1.94 + /* No callback handlers. */ 1.95 + ctxt->event_callback_cs = FLAT_RING1_CS; 1.96 + ctxt->event_callback_eip = 0; 1.97 + ctxt->failsafe_callback_cs = FLAT_RING1_CS; 1.98 + ctxt->failsafe_callback_eip = 0; 1.99 1.100 launch_op.u.builddomain.domain = domain_id; 1.101 launch_op.u.builddomain.num_vifs = atoi(argv[3]);
2.1 --- a/tools/internal/xi_list.c Mon Nov 03 15:16:47 2003 +0000 2.2 +++ b/tools/internal/xi_list.c Mon Nov 03 17:18:05 2003 +0000 2.3 @@ -30,12 +30,9 @@ static char *statestr(int state) 2.4 { 2.5 switch ( state ) 2.6 { 2.7 - case 0: return "RUNNING"; 2.8 - case 1: return "INTERRUPTIBLE"; 2.9 - case 2: return "UNINTERRUPTIBLE"; 2.10 - case 4: return "STOPPED"; 2.11 - case 8: return "DYING"; 2.12 - default: return "UNKNOWN"; 2.13 + case DOMSTATE_ACTIVE: return "ACTIVE"; 2.14 + case DOMSTATE_STOPPED: return "STOPPED"; 2.15 + default: return "UNKNOWN"; 2.16 } 2.17 return NULL; 2.18 }
3.1 --- a/xen/arch/i386/process.c Mon Nov 03 15:16:47 2003 +0000 3.2 +++ b/xen/arch/i386/process.c Mon Nov 03 17:18:05 2003 +0000 3.3 @@ -188,27 +188,6 @@ void machine_power_off(void) 3.4 machine_restart(0); 3.5 } 3.6 3.7 -void exit_thread(void) 3.8 -{ 3.9 - /* nothing to do ... */ 3.10 -} 3.11 - 3.12 -void flush_thread(void) 3.13 -{ 3.14 - struct task_struct *tsk = current; 3.15 - 3.16 - memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); 3.17 - /* 3.18 - * Forget coprocessor state.. 3.19 - */ 3.20 - clear_fpu(tsk); 3.21 - tsk->flags &= ~PF_DONEFPUINIT; 3.22 -} 3.23 - 3.24 -void release_thread(struct task_struct *dead_task) 3.25 -{ 3.26 -} 3.27 - 3.28 void new_thread(struct task_struct *p, 3.29 unsigned long start_pc, 3.30 unsigned long start_stack,
4.1 --- a/xen/common/debug.c Mon Nov 03 15:16:47 2003 +0000 4.2 +++ b/xen/common/debug.c Mon Nov 03 17:18:05 2003 +0000 4.3 @@ -63,8 +63,8 @@ void pdb_do_debug (dom0_op_t *op) 4.4 { 4.5 if (p->state != TASK_STOPPED) 4.6 { 4.7 - cpu_mask = mark_hyp_event(p, _HYP_EVENT_STOP); 4.8 - hyp_event_notify(cpu_mask); 4.9 + cpu_mask = mark_guest_event(p, _EVENT_STOP); 4.10 + guest_event_notify(cpu_mask); 4.11 } 4.12 put_task_struct(p); 4.13 }
5.1 --- a/xen/common/dom0_ops.c Mon Nov 03 15:16:47 2003 +0000 5.2 +++ b/xen/common/dom0_ops.c Mon Nov 03 17:18:05 2003 +0000 5.3 @@ -267,17 +267,24 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 5.4 strcpy (op.u.getdomaininfo.name, p->name); 5.5 op.u.getdomaininfo.processor = p->processor; 5.6 op.u.getdomaininfo.has_cpu = p->has_cpu; 5.7 - op.u.getdomaininfo.state = p->state; 5.8 + op.u.getdomaininfo.state = DOMSTATE_ACTIVE; 5.9 + if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) ) 5.10 + op.u.getdomaininfo.state = DOMSTATE_STOPPED; 5.11 op.u.getdomaininfo.hyp_events = p->hyp_events; 5.12 op.u.getdomaininfo.mcu_advance = p->mcu_advance; 5.13 op.u.getdomaininfo.tot_pages = p->tot_pages; 5.14 op.u.getdomaininfo.cpu_time = p->cpu_time; 5.15 + op.u.getdomaininfo.shared_info_frame = 5.16 + __pa(p->shared_info) >> PAGE_SHIFT; 5.17 if ( p->state == TASK_STOPPED ) 5.18 { 5.19 rmb(); /* Ensure that we see saved register state. */ 5.20 + op.u.getdomaininfo.ctxt.flags = 0; 5.21 memcpy(&op.u.getdomaininfo.ctxt.i386_ctxt, 5.22 &p->shared_info->execution_context, 5.23 sizeof(p->shared_info->execution_context)); 5.24 + if ( p->flags & PF_DONEFPUINIT ) 5.25 + op.u.getdomaininfo.ctxt.flags |= ECF_I387_VALID; 5.26 memcpy(&op.u.getdomaininfo.ctxt.i387_ctxt, 5.27 &p->thread.i387, 5.28 sizeof(p->thread.i387)); 5.29 @@ -308,8 +315,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 5.30 memcpy(op.u.getdomaininfo.ctxt.debugreg, 5.31 p->thread.debugreg, 5.32 sizeof(p->thread.debugreg)); 5.33 - op.u.getdomaininfo.ctxt.domain_time = 5.34 - p->shared_info->domain_time; 5.35 + op.u.getdomaininfo.ctxt.event_callback_cs = p->event_selector; 5.36 + op.u.getdomaininfo.ctxt.event_callback_eip = p->event_address; 5.37 + op.u.getdomaininfo.ctxt.failsafe_callback_cs = 5.38 + p->failsafe_selector; 5.39 + op.u.getdomaininfo.ctxt.failsafe_callback_eip = 5.40 + p->failsafe_address; 5.41 } 5.42 } 5.43 read_unlock_irqrestore(&tasklist_lock, flags);
6.1 --- a/xen/common/domain.c Mon Nov 03 15:16:47 2003 +0000 6.2 +++ b/xen/common/domain.c Mon Nov 03 17:18:05 2003 +0000 6.3 @@ -32,12 +32,9 @@ 6.4 rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; 6.5 struct task_struct *task_hash[TASK_HASH_SIZE]; 6.6 6.7 -/* 6.8 - * create a new domain 6.9 - */ 6.10 struct task_struct *do_createdomain(unsigned int dom_id, unsigned int cpu) 6.11 { 6.12 - int retval, i; 6.13 + int retval; 6.14 struct task_struct *p = NULL; 6.15 unsigned long flags; 6.16 6.17 @@ -68,20 +65,8 @@ struct task_struct *do_createdomain(unsi 6.18 6.19 INIT_LIST_HEAD(&p->physdisk_aces); 6.20 6.21 - SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES); 6.22 - SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS); 6.23 - 6.24 p->addr_limit = USER_DS; 6.25 6.26 - /* 6.27 - * We're basically forcing default RPLs to 1, so that our "what privilege 6.28 - * level are we returning to?" logic works. 6.29 - */ 6.30 - p->failsafe_selector = FLAT_RING1_CS; 6.31 - p->event_selector = FLAT_RING1_CS; 6.32 - p->thread.ss1 = FLAT_RING1_DS; 6.33 - for ( i = 0; i < 256; i++ ) p->thread.traps[i].cs = FLAT_RING1_CS; 6.34 - 6.35 sched_add_domain(p); 6.36 6.37 INIT_LIST_HEAD(&p->pg_head); 6.38 @@ -139,9 +124,11 @@ void __kill_domain(struct task_struct *p 6.39 machine_restart(0); 6.40 } 6.41 6.42 - printk("Killing domain %d\n", p->domain); 6.43 + /* Only allow the domain to be destroyed once. */ 6.44 + if ( !sched_rem_domain(p) ) 6.45 + return; 6.46 6.47 - sched_rem_domain(p); 6.48 + printk("Killing domain %d\n", p->domain); 6.49 6.50 unlink_blkdev_info(p); 6.51 6.52 @@ -215,7 +202,6 @@ void stop_domain(void) 6.53 unlazy_fpu(current); 6.54 wmb(); /* All CPUs must see saved info in state TASK_STOPPED. */ 6.55 set_current_state(TASK_STOPPED); 6.56 - clear_bit(_HYP_EVENT_STOP, ¤t->hyp_events); 6.57 __enter_scheduler(); 6.58 } 6.59 6.60 @@ -229,8 +215,8 @@ long stop_other_domain(unsigned int dom) 6.61 6.62 if ( p->state != TASK_STOPPED ) 6.63 { 6.64 - cpu_mask = mark_hyp_event(p, _HYP_EVENT_STOP); 6.65 - hyp_event_notify(cpu_mask); 6.66 + cpu_mask = mark_guest_event(p, _EVENT_STOP); 6.67 + guest_event_notify(cpu_mask); 6.68 } 6.69 6.70 put_task_struct(p); 6.71 @@ -332,13 +318,14 @@ void release_task(struct task_struct *p) 6.72 } 6.73 6.74 6.75 -/* final_setup_guestos is used for final setup and launching of domains other 6.76 +/* 6.77 + * final_setup_guestos is used for final setup and launching of domains other 6.78 * than domain 0. ie. the domains that are being built by the userspace dom0 6.79 * domain builder. 6.80 */ 6.81 int final_setup_guestos(struct task_struct *p, dom0_builddomain_t *builddomain) 6.82 { 6.83 - start_info_t * virt_startinfo_addr; 6.84 + start_info_t *virt_startinfo_addr; 6.85 unsigned long phys_l2tab; 6.86 net_ring_t *shared_rings; 6.87 net_vif_t *net_vif; 6.88 @@ -346,7 +333,10 @@ int final_setup_guestos(struct task_stru 6.89 6.90 if ( (p->flags & PF_CONSTRUCTED) ) 6.91 return -EINVAL; 6.92 - 6.93 + 6.94 + p->flags &= ~PF_DONEFPUINIT; 6.95 + if ( builddomain->ctxt.flags & ECF_I387_VALID ) 6.96 + p->flags |= PF_DONEFPUINIT; 6.97 memcpy(&p->shared_info->execution_context, 6.98 &builddomain->ctxt.i386_ctxt, 6.99 sizeof(p->shared_info->execution_context)); 6.100 @@ -371,6 +361,10 @@ int final_setup_guestos(struct task_stru 6.101 memcpy(p->thread.debugreg, 6.102 builddomain->ctxt.debugreg, 6.103 sizeof(p->thread.debugreg)); 6.104 + p->event_selector = builddomain->ctxt.event_callback_cs; 6.105 + p->event_address = builddomain->ctxt.event_callback_eip; 6.106 + p->failsafe_selector = builddomain->ctxt.failsafe_callback_cs; 6.107 + p->failsafe_address = builddomain->ctxt.failsafe_callback_eip; 6.108 6.109 /* NB. Page base must already be pinned! */ 6.110 phys_l2tab = builddomain->ctxt.pt_base; 6.111 @@ -378,25 +372,19 @@ int final_setup_guestos(struct task_stru 6.112 get_page_type(&frame_table[phys_l2tab>>PAGE_SHIFT]); 6.113 get_page_tot(&frame_table[phys_l2tab>>PAGE_SHIFT]); 6.114 6.115 - /* set up the shared info structure */ 6.116 + /* Set up the shared info structure. */ 6.117 update_dom_time(p->shared_info); 6.118 - p->shared_info->domain_time = builddomain->ctxt.domain_time; 6.119 6.120 - /* we pass start info struct to guest os as function parameter on stack */ 6.121 virt_startinfo_addr = (start_info_t *)builddomain->virt_startinfo_addr; 6.122 6.123 - /* we need to populate start_info struct within the context of the 6.124 - * new domain. thus, temporarely install its pagetables. 6.125 + /* 6.126 + * We need to populate start_info struct within the context of the new 6.127 + * domain. Thus temporarely install its pagetables. 6.128 */ 6.129 __cli(); 6.130 __asm__ __volatile__ ( 6.131 "mov %%eax,%%cr3" : : "a" (pagetable_val(p->mm.pagetable))); 6.132 6.133 - virt_startinfo_addr->nr_pages = p->tot_pages; 6.134 - virt_startinfo_addr->shared_info = virt_to_phys(p->shared_info); 6.135 - virt_startinfo_addr->dom_id = p->domain; 6.136 - virt_startinfo_addr->flags = IS_PRIV(p) ? SIF_PRIVILEGED : 0; 6.137 - 6.138 /* Add virtual network interfaces and point to them in startinfo. */ 6.139 while (builddomain->num_vifs-- > 0) { 6.140 net_vif = create_net_vif(p->domain); 6.141 @@ -437,7 +425,8 @@ static unsigned long alloc_page_from_dom 6.142 return ret; 6.143 } 6.144 6.145 -/* setup_guestos is used for building dom0 solely. other domains are built in 6.146 +/* 6.147 + * setup_guestos is used for building dom0 solely. other domains are built in 6.148 * userspace dom0 and final setup is being done by final_setup_guestos. 6.149 */ 6.150 int setup_guestos(struct task_struct *p, dom0_createdomain_t *params, 6.151 @@ -513,6 +502,19 @@ int setup_guestos(struct task_struct *p, 6.152 printk("DOM%d: Guest OS virtual load address is %08lx\n", dom, 6.153 virt_load_address); 6.154 6.155 + SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES); 6.156 + SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS); 6.157 + 6.158 + /* 6.159 + * We're basically forcing default RPLs to 1, so that our "what privilege 6.160 + * level are we returning to?" logic works. 6.161 + */ 6.162 + p->failsafe_selector = FLAT_RING1_CS; 6.163 + p->event_selector = FLAT_RING1_CS; 6.164 + p->thread.ss1 = FLAT_RING1_DS; 6.165 + for ( i = 0; i < 256; i++ ) 6.166 + p->thread.traps[i].cs = FLAT_RING1_CS; 6.167 + 6.168 /* 6.169 * WARNING: The new domain must have its 'processor' field 6.170 * filled in by now !!
7.1 --- a/xen/common/event.c Mon Nov 03 15:16:47 2003 +0000 7.2 +++ b/xen/common/event.c Mon Nov 03 17:18:05 2003 +0000 7.3 @@ -18,7 +18,6 @@ static hyp_event_callback_fn_t event_cal 7.4 { 7.5 __enter_scheduler, 7.6 kill_domain, 7.7 - stop_domain 7.8 }; 7.9 7.10 /* Handle outstanding events for the currently-executing domain. */
8.1 --- a/xen/common/schedule.c Mon Nov 03 15:16:47 2003 +0000 8.2 +++ b/xen/common/schedule.c Mon Nov 03 17:18:05 2003 +0000 8.3 @@ -24,7 +24,6 @@ 8.4 #include <xeno/timer.h> 8.5 #include <xeno/perfc.h> 8.6 8.7 - 8.8 #undef SCHEDULER_TRACE 8.9 #ifdef SCHEDULER_TRACE 8.10 #define TRC(_x) _x 8.11 @@ -138,9 +137,13 @@ void sched_add_domain(struct task_struct 8.12 } 8.13 } 8.14 8.15 -void sched_rem_domain(struct task_struct *p) 8.16 +int sched_rem_domain(struct task_struct *p) 8.17 { 8.18 - p->state = TASK_DYING; 8.19 + int x, y = p->state; 8.20 + do { 8.21 + if ( (x = y) == TASK_DYING ) return 0; 8.22 + } while ( (y = cmpxchg(&p->state, x, TASK_DYING)) != x ); 8.23 + return 1; 8.24 } 8.25 8.26 8.27 @@ -227,6 +230,12 @@ long do_sched_op(unsigned long op) 8.28 break; 8.29 } 8.30 8.31 + case SCHEDOP_stop: 8.32 + { 8.33 + stop_domain(); 8.34 + break; 8.35 + } 8.36 + 8.37 default: 8.38 ret = -ENOSYS; 8.39 }
9.1 --- a/xen/include/asm-i386/processor.h Mon Nov 03 15:16:47 2003 +0000 9.2 +++ b/xen/include/asm-i386/processor.h Mon Nov 03 17:18:05 2003 +0000 9.3 @@ -437,21 +437,6 @@ long set_gdt(struct task_struct *p, 9.4 unsigned long *frames, 9.5 unsigned int entries); 9.6 9.7 -/* Free all resources held by a thread. */ 9.8 -extern void release_thread(struct task_struct *); 9.9 -/* 9.10 - * create a kernel thread without removing it from tasklists 9.11 - */ 9.12 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 9.13 - 9.14 -/* Copy and release all segment info associated with a VM */ 9.15 -extern void copy_segments(struct task_struct *p, struct mm_struct * mm); 9.16 -extern void release_segments(struct mm_struct * mm); 9.17 - 9.18 -unsigned long get_wchan(struct task_struct *p); 9.19 -#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) 9.20 -#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) 9.21 - 9.22 struct microcode { 9.23 unsigned int hdrver; 9.24 unsigned int rev;
10.1 --- a/xen/include/asm-i386/system.h Mon Nov 03 15:16:47 2003 +0000 10.2 +++ b/xen/include/asm-i386/system.h Mon Nov 03 17:18:05 2003 +0000 10.3 @@ -63,9 +63,6 @@ static inline unsigned long __xchg(unsig 10.4 * indicated by comparing RETURN with OLD. 10.5 */ 10.6 10.7 -#ifdef CONFIG_X86_CMPXCHG 10.8 -#define __HAVE_ARCH_CMPXCHG 1 10.9 - 10.10 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, 10.11 unsigned long new, int size) 10.12 { 10.13 @@ -97,10 +94,6 @@ static inline unsigned long __cmpxchg(vo 10.14 ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ 10.15 (unsigned long)(n),sizeof(*(ptr)))) 10.16 10.17 -#else 10.18 -/* Compiling for a 386 proper. Is it worth implementing via cli/sti? */ 10.19 -#endif 10.20 - 10.21 /* 10.22 * Force strict CPU ordering. 10.23 * And yes, this is required on UP too when we're talking
11.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h Mon Nov 03 15:16:47 2003 +0000 11.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h Mon Nov 03 17:18:05 2003 +0000 11.3 @@ -17,7 +17,7 @@ 11.4 * This makes sure that old versions of dom0 tools will stop working in a 11.5 * well-defined way (rather than crashing the machine, for instance). 11.6 */ 11.7 -#define DOM0_INTERFACE_VERSION 0xAAAA0002 11.8 +#define DOM0_INTERFACE_VERSION 0xAAAA0003 11.9 11.10 11.11 /* 11.12 @@ -26,6 +26,8 @@ 11.13 */ 11.14 typedef struct full_execution_context_st 11.15 { 11.16 +#define ECF_I387_VALID (1<<0) 11.17 + unsigned long flags; 11.18 execution_context_t i386_ctxt; /* User-level CPU registers */ 11.19 char i387_ctxt[256]; /* User-level FPU registers */ 11.20 trap_info_t trap_ctxt[256]; /* Virtual IDT */ 11.21 @@ -35,7 +37,10 @@ typedef struct full_execution_context_st 11.22 unsigned long ring1_ss, ring1_esp; /* Virtual TSS (only SS1/ESP1) */ 11.23 unsigned long pt_base; /* CR3 (pagetable base) */ 11.24 unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */ 11.25 - u64 domain_time; /* Domain virtual time */ 11.26 + unsigned long event_callback_cs; /* CS:EIP of event callback */ 11.27 + unsigned long event_callback_eip; 11.28 + unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */ 11.29 + unsigned long failsafe_callback_eip; 11.30 } full_execution_context_t; 11.31 11.32 #define MAX_CMD_LEN 256 11.33 @@ -121,11 +126,14 @@ typedef struct dom0_getdomaininfo_st 11.34 char name[MAX_DOMAIN_NAME]; 11.35 int processor; 11.36 int has_cpu; 11.37 +#define DOMSTATE_ACTIVE 0 11.38 +#define DOMSTATE_STOPPED 1 11.39 int state; 11.40 int hyp_events; 11.41 unsigned long mcu_advance; 11.42 unsigned int tot_pages; 11.43 long long cpu_time; 11.44 + unsigned long shared_info_frame; /* MFN of shared_info struct */ 11.45 full_execution_context_t ctxt; 11.46 } dom0_getdomaininfo_t; 11.47
12.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h Mon Nov 03 15:16:47 2003 +0000 12.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h Mon Nov 03 17:18:05 2003 +0000 12.3 @@ -90,6 +90,7 @@ 12.4 #define EVENT_DEBUG 0x08 /* Request guest to dump debug info (gross!) */ 12.5 #define EVENT_NET 0x10 /* There are packets for transmission. */ 12.6 #define EVENT_PS2 0x20 /* PS/2 keyboard or mouse event(s) */ 12.7 +#define EVENT_STOP 0x40 /* Prepare for stopping and possible pickling */ 12.8 12.9 /* Bit offsets, as opposed to the above masks. */ 12.10 #define _EVENT_BLKDEV 0 12.11 @@ -98,6 +99,7 @@ 12.12 #define _EVENT_DEBUG 3 12.13 #define _EVENT_NET 4 12.14 #define _EVENT_PS2 5 12.15 +#define _EVENT_STOP 6 12.16 12.17 /* 12.18 * Virtual addresses beyond this are not modifiable by guest OSes. The 12.19 @@ -156,6 +158,7 @@ 12.20 */ 12.21 #define SCHEDOP_yield 0 12.22 #define SCHEDOP_exit 1 12.23 +#define SCHEDOP_stop 2 12.24 12.25 12.26
13.1 --- a/xen/include/xeno/sched.h Mon Nov 03 15:16:47 2003 +0000 13.2 +++ b/xen/include/xeno/sched.h Mon Nov 03 17:18:05 2003 +0000 13.3 @@ -31,7 +31,6 @@ extern struct mm_struct init_mm; 13.4 13.5 #define _HYP_EVENT_NEED_RESCHED 0 13.6 #define _HYP_EVENT_DIE 1 13.7 -#define _HYP_EVENT_STOP 2 13.8 13.9 #define PF_DONEFPUINIT 0x1 /* Has the FPU been initialised for this task? */ 13.10 #define PF_USEDFPU 0x2 /* Has this task used the FPU since last save? */ 13.11 @@ -148,9 +147,6 @@ struct task_struct 13.12 * arbitrary event or timer. 13.13 * TASK_STOPPED: Domain is sopped. 13.14 * TASK_DYING: Domain is about to cross over to the land of the dead. 13.15 - * 13.16 - * If you update these then please update the mapping to text names in 13.17 - * xi_list. 13.18 */ 13.19 13.20 #define TASK_RUNNING 0 13.21 @@ -214,8 +210,6 @@ void new_thread(struct task_struct *p, 13.22 unsigned long start_pc, 13.23 unsigned long start_stack, 13.24 unsigned long start_info); 13.25 -extern void flush_thread(void); 13.26 -extern void exit_thread(void); 13.27 13.28 /* Linux puts these here for some reason! */ 13.29 extern int request_irq(unsigned int, 13.30 @@ -235,7 +229,7 @@ extern unsigned long wait_init_idle; 13.31 void scheduler_init(void); 13.32 void schedulers_start(void); 13.33 void sched_add_domain(struct task_struct *p); 13.34 -void sched_rem_domain(struct task_struct *p); 13.35 +int sched_rem_domain(struct task_struct *p); 13.36 long sched_bvtctl(unsigned long ctx_allow); 13.37 long sched_adjdom(int dom, unsigned long mcu_adv, unsigned long warp, 13.38 unsigned long warpl, unsigned long warpu);
14.1 --- a/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c Mon Nov 03 15:16:47 2003 +0000 14.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c Mon Nov 03 17:18:05 2003 +0000 14.3 @@ -50,7 +50,7 @@ 14.4 * Point at the empty zero page to start with. We map the real shared_info 14.5 * page as soon as fixmap is up and running. 14.6 */ 14.7 -shared_info_t *HYPERVISOR_shared_info = empty_zero_page; 14.8 +shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; 14.9 14.10 unsigned long *phys_to_machine_mapping; 14.11 14.12 @@ -1048,3 +1048,22 @@ static int __init setup_death_event(void 14.13 } 14.14 14.15 __initcall(setup_death_event); 14.16 + 14.17 + 14.18 +/****************************************************************************** 14.19 + * Stop/pickle callback handling. 14.20 + */ 14.21 + 14.22 +static void time_to_stop(int irq, void *unused, struct pt_regs *regs) 14.23 +{ 14.24 + HYPERVISOR_stop(); 14.25 +} 14.26 + 14.27 +static int __init setup_stop_event(void) 14.28 +{ 14.29 + (void)request_irq(_EVENT_STOP, time_to_stop, 0, "stop", NULL); 14.30 + return 0; 14.31 +} 14.32 + 14.33 +__initcall(setup_stop_event); 14.34 +
15.1 --- a/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h Mon Nov 03 15:16:47 2003 +0000 15.2 +++ b/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h Mon Nov 03 17:18:05 2003 +0000 15.3 @@ -263,6 +263,17 @@ static inline int HYPERVISOR_exit(void) 15.4 return ret; 15.5 } 15.6 15.7 +static inline int HYPERVISOR_stop(void) 15.8 +{ 15.9 + int ret; 15.10 + __asm__ __volatile__ ( 15.11 + TRAP_INSTR 15.12 + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 15.13 + "b" (SCHEDOP_stop) ); 15.14 + 15.15 + return ret; 15.16 +} 15.17 + 15.18 static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op) 15.19 { 15.20 int ret;