]> xenbits.xensource.com Git - xen.git/commitdiff
bitkeeper revision 1.1236.27.1 (42337175wSkxS0D7A1TSBWgZsfOczg)
authorkmacy@shemp.lab.netapp.com <kmacy@shemp.lab.netapp.com>
Sat, 12 Mar 2005 22:47:17 +0000 (22:47 +0000)
committerkmacy@shemp.lab.netapp.com <kmacy@shemp.lab.netapp.com>
Sat, 12 Mar 2005 22:47:17 +0000 (22:47 +0000)
Add user-level debug support
Signed-off-by: Kip Macy
17 files changed:
.rootkeys
BitKeeper/etc/logging_ok
tools/libxc/Makefile
tools/libxc/xc_linux_build.c
tools/libxc/xc_linux_restore.c
tools/libxc/xc_plan9_build.c
tools/libxc/xc_ptrace.c [new file with mode: 0644]
tools/libxc/xc_vmx_build.c
xen/Rules.mk
xen/arch/ia64/domain.c
xen/arch/x86/domain.c
xen/arch/x86/traps.c
xen/common/dom0_ops.c
xen/common/domain.c
xen/include/public/dom0_ops.h
xen/include/xen/domain.h
xen/include/xen/sched.h

index 3ae07f2290d41f908289265cb2f2b4c285fcfe44..6732920706b2271abe70350ca6064bd00d6f90c4 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 41cc934aO1m6NxEh_8eDr9bJIMoLFA tools/libxc/xc_plan9_build.c
 3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c
 3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h
+42337174PxyzzPk62raDiYCIsfStDg tools/libxc/xc_ptrace.c
 40589968UQFnJeOMn8UIFLbXBuwXjw tools/libxc/xc_rrobin.c
 41dde8b0pLfAKMs_L9Uri2hnzHiCRQ tools/libxc/xc_vmx_build.c
 40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile
index fde76498a42b5a503394b0d43e9c46a508ea5649..da2feeb756c4bce64aa9739590504b5114cc27a5 100644 (file)
@@ -45,6 +45,7 @@ kaf24@plym.cl.cam.ac.uk
 kaf24@scramble.cl.cam.ac.uk
 kaf24@striker.cl.cam.ac.uk
 kaf24@viper.(none)
+kmacy@shemp.lab.netapp.com
 laudney@eclipse.(none)
 lynx@idefix.cl.cam.ac.uk
 maf46@burn.cl.cam.ac.uk
index 598a567e6b084290a6d5674c8c8e00408d2648f0..cc33da70461db0e95f33c3ae359a736f012777ab 100644 (file)
@@ -29,6 +29,7 @@ SRCS     += xc_linux_save.c
 SRCS     += xc_misc.c
 SRCS     += xc_physdev.c
 SRCS     += xc_private.c
+SRCS     += xc_ptrace.c
 SRCS     += xc_rrobin.c
 SRCS     += xc_vmx_build.c
 
index 2a41fa6b58394ce95b6d9b637df08e1bae7586bf..919800c1083bc18ff4ebdc3e0d12e7ab09a01c49 100644 (file)
@@ -459,10 +459,11 @@ int xc_linux_build(int xc_handle,
 
     memset( &launch_op, 0, sizeof(launch_op) );
 
-    launch_op.u.builddomain.domain   = (domid_t)domid;
-    launch_op.u.builddomain.ctxt = ctxt;
+    launch_op.u.setdomaininfo.domain   = (domid_t)domid;
+    launch_op.u.setdomaininfo.exec_domain = 0;
+    launch_op.u.setdomaininfo.ctxt = ctxt;
 
-    launch_op.cmd = DOM0_BUILDDOMAIN;
+    launch_op.cmd = DOM0_SETDOMAININFO;
     rc = do_dom0_op(xc_handle, &launch_op);
     
     return rc;
index b4ad94479d55eb71679b5b2fa9e38e7b0a471cc7..938f219ec76aa485d682691c3bc39e6d263d53bc 100644 (file)
@@ -638,9 +638,10 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
     xcio_info(ioctxt, "Domain ready to be built.\n");
 
-    op.cmd = DOM0_BUILDDOMAIN;
-    op.u.builddomain.domain   = (domid_t)dom;
-    op.u.builddomain.ctxt = &ctxt;
+    op.cmd = DOM0_SETDOMAININFO;
+    op.u.setdomaininfo.domain   = (domid_t)dom;
+    op.u.setdomaininfo.exec_domain   = 0;
+    op.u.setdomaininfo.ctxt = &ctxt;
     rc = do_dom0_op(xc_handle, &op);
 
     if ( rc != 0 )
index a7e37c13a5e2e11f999af593fa14031440e79229..c6778d44bc76ce4fc3b15ecaec69b1d83cec038b 100755 (executable)
@@ -533,10 +533,11 @@ xc_plan9_build(int xc_handle,
 
        memset(&launch_op, 0, sizeof (launch_op));
 
-       launch_op.u.builddomain.domain = (domid_t) domid;
-       //  launch_op.u.builddomain.num_vifs = 1;
-       launch_op.u.builddomain.ctxt = ctxt;
-       launch_op.cmd = DOM0_BUILDDOMAIN;
+       launch_op.u.setdomaininfo.domain = (domid_t) domid;
+       launch_op.u.setdomaininfo.exec_domain = 0;
+       //  launch_op.u.setdomaininfo.num_vifs = 1;
+       launch_op.u.setdomaininfo.ctxt = ctxt;
+       launch_op.cmd = DOM0_SETDOMAININFO;
        rc = do_dom0_op(xc_handle, &launch_op);
 
        fprintf(stderr, "RC is %d\n", rc);
diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c
new file mode 100644 (file)
index 0000000..ea0b9f4
--- /dev/null
@@ -0,0 +1,341 @@
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include "xc_private.h"
+#include <asm/elf.h>
+#include <time.h>
+
+
+#define BSD_PAGE_MASK  (PAGE_SIZE-1)
+#define        PG_FRAME        (~((unsigned long)BSD_PAGE_MASK)
+#define PDRSHIFT        22
+#define        PSL_T           0x00000100      /* trace enable bit */
+
+
+/*
+ * long  
+ * ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
+ */
+
+long xc_ptrace(enum __ptrace_request request, 
+              pid_t pid, void *addr, void *data);
+int waitdomain(int domain, int *status, int options);
+
+char * ptrace_names[] = {
+    "PTRACE_TRACEME",
+    "PTRACE_PEEKTEXT",
+    "PTRACE_PEEKDATA",
+    "PTRACE_PEEKUSER",
+    "PTRACE_POKETEXT",
+    "PTRACE_POKEDATA",
+    "PTRACE_POKEUSER",
+    "PTRACE_CONT",
+    "PTRACE_KILL",
+    "PTRACE_SINGLESTEP",
+    "PTRACE_INVALID",
+    "PTRACE_INVALID",
+    "PTRACE_GETREGS",
+    "PTRACE_SETREGS",
+    "PTRACE_GETFPREGS",
+    "PTRACE_SETFPREGS",
+    "PTRACE_ATTACH",
+    "PTRACE_DETACH",
+    "PTRACE_GETFPXREGS",
+    "PTRACE_SETFPXREGS",
+    "PTRACE_INVALID",
+    "PTRACE_INVALID",
+    "PTRACE_INVALID",
+    "PTRACE_INVALID",
+    "PTRACE_SYSCALL",
+};
+
+struct gdb_regs {
+        long ebx; /* 0 */
+        long ecx; /* 4 */
+        long edx; /* 8 */
+        long esi; /* 12 */
+        long edi; /* 16 */
+        long ebp; /* 20 */
+        long eax; /* 24 */ 
+        int  xds; /* 28 */
+        int  xes; /* 32 */
+       int  xfs; /* 36 */
+       int  xgs; /* 40 */
+       long orig_eax; /* 44 */
+        long eip;    /* 48 */
+        int  xcs;    /* 52 */
+        long eflags; /* 56 */
+        long esp;    /* 60 */     
+       int  xss;    /* 64 */
+};
+#define printval(x) printf("%s = %lx\n", #x, (long)x);
+#define SET_PT_REGS(pt, xc) \
+{ \
+pt.ebx = xc.ebx; \
+pt.ecx = xc.ecx; \
+pt.edx = xc.edx; \
+pt.esi = xc.esi; \
+pt.edi = xc.edi; \
+pt.ebp = xc.ebp; \
+pt.eax = xc.eax; \
+pt.eip = xc.eip; \
+pt.xcs = xc.cs; \
+pt.eflags = xc.eflags; \
+pt.esp = xc.esp; \
+pt.xss = xc.ss; \
+pt.xes = xc.es; \
+pt.xds = xc.ds; \
+pt.xfs = xc.fs; \
+pt.xgs = xc.gs; \
+}
+
+#define SET_XC_REGS(pt, xc) \
+{ \
+xc.ebx = pt->ebx; \
+xc.ecx = pt->ecx; \
+xc.edx = pt->edx; \
+xc.esi = pt->esi; \
+xc.edi = pt->edi; \
+xc.ebp = pt->ebp; \
+xc.eax = pt->eax; \
+xc.eip = pt->eip; \
+xc.cs = pt->xcs; \
+xc.eflags = pt->eflags; \
+xc.esp = pt->esp; \
+xc.ss = pt->xss; \
+xc.es = pt->xes; \
+xc.ds = pt->xds; \
+xc.fs = pt->xfs; \
+xc.gs = pt->xgs; \
+}
+
+
+#define vtopdi(va) ((va) >> PDRSHIFT)
+#define vtopti(va) (((va) >> PAGE_SHIFT) & BSD_PAGE_MASK)
+
+/* XXX application state */
+
+
+static int xc_handle;
+static int regs_valid;
+static unsigned long cr3;
+static full_execution_context_t ctxt;
+
+/* --------------------- */
+
+static void *
+map_domain_va(unsigned long domid, void * guest_va)
+{
+    unsigned long pde, page;
+    unsigned long va = (unsigned long)guest_va;
+
+    static unsigned long cr3_phys;
+    static unsigned long *cr3_virt;
+    static unsigned long pde_phys;
+    static unsigned long *pde_virt;
+    static unsigned long page_phys;
+    static unsigned long *page_virt;
+
+    if (cr3 != cr3_phys) 
+    {
+       cr3_phys = cr3;
+       if (cr3_virt)
+           munmap(cr3_virt, PAGE_SIZE);
+       if ((cr3_virt = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                            PROT_READ,
+                                            cr3_phys >> PAGE_SHIFT)) == NULL)
+           goto error_out;
+    } 
+    pde = cr3_virt[vtopdi(va)];
+    if (pde != pde_phys) 
+    {
+       pde_phys = pde;
+       if (pde_virt)
+           munmap(pde_virt, PAGE_SIZE);
+       if ((pde_virt = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                            PROT_READ,
+                                            pde_phys >> PAGE_SHIFT)) == NULL)
+           goto error_out;
+    }
+    page = pde_virt[vtopti(va)];
+    if (page != page_phys) 
+    {
+       page_phys = page;
+       if (page_virt)
+           munmap(page_virt, PAGE_SIZE);
+       if ((page_virt = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                            PROT_READ|PROT_WRITE,
+                                            page_phys >> PAGE_SHIFT)) == NULL)
+           goto error_out;
+    }  
+    return (void *)(((unsigned long)page_virt) | (va & BSD_PAGE_MASK));
+
+ error_out:
+    return 0;
+}
+
+int 
+waitdomain(int domain, int *status, int options)
+{
+    dom0_op_t op;
+    int retval;
+    full_execution_context_t ctxt;
+    struct timespec ts;
+    ts.tv_sec = 0;
+    ts.tv_nsec = 10*1000*1000;
+
+    if (!xc_handle)
+       if ((xc_handle = xc_interface_open()) < 0) 
+       {
+           printf("xc_interface_open failed\n");
+           return -1;
+       }
+    op.cmd = DOM0_GETDOMAININFO;
+    op.u.getdomaininfo.domain = domain;
+    op.u.getdomaininfo.exec_domain = 0;
+    op.u.getdomaininfo.ctxt = &ctxt;
+ retry:
+
+    retval = do_dom0_op(xc_handle, &op);
+    if (retval) {
+       printf("getdomaininfo failed\n");
+       goto done;
+    }
+    *status = op.u.getdomaininfo.flags;
+    
+    if (options & WNOHANG)
+       goto done;
+       
+
+    if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)) {       
+       nanosleep(&ts,NULL);
+       goto retry;
+    }
+ done:
+    return retval;
+
+}
+
+long
+xc_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data)
+{
+    dom0_op_t op;
+    int status = 0;
+    xc_domaininfo_t info;
+    struct gdb_regs pt;
+    long retval = 0;
+    long *guest_va;
+
+    op.interface_version = DOM0_INTERFACE_VERSION;
+    
+    if (!xc_handle)
+       if ((xc_handle = xc_interface_open()) < 0)
+           return -1;
+#if 0
+    printf("%20s %d, %p, %p \n", ptrace_names[request], pid, addr, data);
+#endif
+    switch (request) { 
+    case PTRACE_PEEKTEXT:
+    case PTRACE_PEEKDATA:
+    case PTRACE_POKETEXT:
+    case PTRACE_POKEDATA:
+       if ((guest_va = (unsigned long *)map_domain_va(pid, addr)) == NULL)
+           goto done;
+
+       if (request == PTRACE_PEEKTEXT || request == PTRACE_PEEKDATA)
+           retval = *guest_va;
+       else
+           *guest_va = (unsigned long)data;
+       break;
+    case PTRACE_GETREGS:
+    case PTRACE_GETFPREGS:
+    case PTRACE_GETFPXREGS:
+       /* XXX hard-coding UP */
+       retval = xc_domain_getfullinfo(xc_handle, pid, 0, &info, &ctxt);
+
+       if (retval) {
+           printf("getfullinfo failed\n");
+           goto done;
+       }
+       if (request == PTRACE_GETREGS) {
+               SET_PT_REGS(pt, ctxt.cpu_ctxt); 
+               memcpy(data, &pt, sizeof(elf_gregset_t));
+       } else if (request == PTRACE_GETFPREGS)
+           memcpy(data, &ctxt.fpu_ctxt, sizeof(elf_fpregset_t));
+       else /*if (request == PTRACE_GETFPXREGS)*/
+           memcpy(data, &ctxt.fpu_ctxt, sizeof(elf_fpxregset_t));
+       cr3 = ctxt.pt_base;
+       regs_valid = 1;
+       break;
+    case PTRACE_SETREGS:
+       op.cmd = DOM0_SETDOMAININFO;
+       SET_XC_REGS(((struct gdb_regs *)data), ctxt.cpu_ctxt);
+       op.u.setdomaininfo.domain = pid;
+       /* XXX need to understand multiple exec_domains */
+       op.u.setdomaininfo.exec_domain = 0;
+       op.u.setdomaininfo.ctxt = &ctxt;
+       retval = do_dom0_op(xc_handle, &op);
+       if (retval)
+           goto done;
+
+       break;
+    case PTRACE_ATTACH:
+       op.cmd = DOM0_GETDOMAININFO;
+       op.u.getdomaininfo.domain = pid;
+       op.u.getdomaininfo.exec_domain = 0;
+       op.u.getdomaininfo.ctxt = &ctxt;
+       retval = do_dom0_op(xc_handle, &op);
+       if (retval) {
+           perror("dom0 op failed");
+           goto done;
+       }
+       if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) {
+           printf("domain currently paused\n");
+           goto done;
+       }
+       printf("domain not currently paused\n");
+       op.cmd = DOM0_PAUSEDOMAIN;
+       op.u.pausedomain.domain = pid;
+       retval = do_dom0_op(xc_handle, &op);
+       break;
+    case PTRACE_SINGLESTEP:
+       ctxt.cpu_ctxt.eflags |= PSL_T;
+       op.cmd = DOM0_SETDOMAININFO;
+       op.u.setdomaininfo.domain = pid;
+       op.u.setdomaininfo.exec_domain = 0;
+       op.u.setdomaininfo.ctxt = &ctxt;
+       retval = do_dom0_op(xc_handle, &op);    
+       if (retval) {
+           perror("dom0 op failed");
+           goto done;
+       }
+    case PTRACE_CONT:
+    case PTRACE_DETACH:
+       regs_valid = 0;
+       op.cmd = DOM0_UNPAUSEDOMAIN;
+       op.u.unpausedomain.domain = pid > 0 ? pid : -pid;
+       retval = do_dom0_op(xc_handle, &op);
+       break;
+    case PTRACE_SETFPREGS:
+    case PTRACE_SETFPXREGS:
+    case PTRACE_PEEKUSER:
+    case PTRACE_POKEUSER:
+    case PTRACE_SYSCALL:
+    case PTRACE_KILL:
+#ifdef DEBUG
+       printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
+#endif
+       /* XXX not yet supported */
+       status = ENOSYS;
+       break;
+    case PTRACE_TRACEME:
+       printf("PTRACE_TRACEME is an invalid request under Xen\n");
+       status = EINVAL;
+    }
+    
+    if (status) {
+       errno = status;
+       retval = -1;
+    }
+ done:
+    return retval;
+}
index 07017291ec6c56cae5cee8931d7d4ebbe9d8ca40..b2b40545239369fd3fedccde09c1548b57a680d4 100644 (file)
@@ -603,10 +603,11 @@ int xc_vmx_build(int xc_handle,
 
     memset( &launch_op, 0, sizeof(launch_op) );
 
-    launch_op.u.builddomain.domain   = (domid_t)domid;
-    launch_op.u.builddomain.ctxt = ctxt;
+    launch_op.u.setdomaininfo.domain   = (domid_t)domid;
+    launch_op.u.setdomaininfo.exec_domain = 0;
+    launch_op.u.setdomaininfo.ctxt = ctxt;
 
-    launch_op.cmd = DOM0_BUILDDOMAIN;
+    launch_op.cmd = DOM0_SETDOMAININFO;
     rc = do_dom0_op(xc_handle, &launch_op);
     return rc;
 
index d8de5c353532366e92d99de7c7c8376b03ac2cc0..e262d690c8070bf259236376f013eca64a276575 100644 (file)
@@ -1,6 +1,7 @@
 
 verbose     ?= n
 debug       ?= n
+debugger    ?= n
 perfc       ?= n
 trace       ?= n
 optimize    ?= y
@@ -54,6 +55,10 @@ else
 CFLAGS += -DVERBOSE
 endif
 
+ifeq ($(debugger),y)
+CFLAGS += -DXEN_UDB
+endif
+
 ifeq ($(crash_debug),y)
 CFLAGS += -g -DCRASH_DEBUG
 endif
index c5f1533f88be729f1e8ecb029a6a0cc859f8f253..612a2059d04f2d53d55c7df284aefd8f8b39a379 100644 (file)
@@ -200,7 +200,7 @@ void arch_do_boot_vcpu(struct exec_domain *p)
        return;
 }
 
-int arch_final_setup_guest(struct exec_domain *p, full_execution_context_t *c)
+int arch_set_info_guest(struct exec_domain *p, full_execution_context_t *c)
 {
        dummy();
        return 1;
index cfb60bfcb5c00809b6dbcd8430b1f39b13013246..1b48f8822b565b5ee617f0988ddc6eb55733f18d 100644 (file)
@@ -423,13 +423,23 @@ out:
 
 
 /* This is called by arch_final_setup_guest and do_boot_vcpu */
-int arch_final_setup_guest(
+int arch_set_info_guest(
     struct exec_domain *ed, full_execution_context_t *c)
 {
     struct domain *d = ed->domain;
     unsigned long phys_basetab;
     int i, rc;
 
+    /*
+     * This is sufficient! If the descriptor DPL differs from CS RPL then we'll
+     * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically.
+     * If SS RPL or DPL differs from CS RPL then we'll #GP.
+     */
+    if (!(c->flags & ECF_VMX_GUEST)) 
+        if ( ((c->cpu_ctxt.cs & 3) == 0) ||
+             ((c->cpu_ctxt.ss & 3) == 0) )
+                return -EINVAL;
+
     clear_bit(EDF_DONEFPUINIT, &ed->ed_flags);
     if ( c->flags & ECF_I387_VALID )
         set_bit(EDF_DONEFPUINIT, &ed->ed_flags);
@@ -441,6 +451,11 @@ int arch_final_setup_guest(
     memcpy(&ed->arch.user_ctxt,
            &c->cpu_ctxt,
            sizeof(ed->arch.user_ctxt));
+
+    memcpy(&ed->arch.i387,
+           &c->fpu_ctxt,
+           sizeof(ed->arch.i387));
+
     /* IOPL privileges are virtualised. */
     ed->arch.iopl = (ed->arch.user_ctxt.eflags >> 12) & 3;
     ed->arch.user_ctxt.eflags &= ~EF_IOPL;
@@ -449,19 +464,8 @@ int arch_final_setup_guest(
     if (!IS_PRIV(d))
         ed->arch.user_ctxt.eflags &= 0xffffcfff;
 
-    /*
-     * This is sufficient! If the descriptor DPL differs from CS RPL then we'll
-     * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically.
-     * If SS RPL or DPL differs from CS RPL then we'll #GP.
-     */
-    if (!(c->flags & ECF_VMX_GUEST)) 
-        if ( ((ed->arch.user_ctxt.cs & 3) == 0) ||
-             ((ed->arch.user_ctxt.ss & 3) == 0) )
-                return -EINVAL;
-
-    memcpy(&ed->arch.i387,
-           &c->fpu_ctxt,
-           sizeof(ed->arch.i387));
+    if (test_bit(EDF_DONEINIT, &ed->ed_flags))
+        return 0;
 
     memcpy(ed->arch.traps,
            &c->trap_ctxt,
@@ -509,10 +513,14 @@ int arch_final_setup_guest(
 #endif
 
     update_pagetables(ed);
+    
+    /* Don't redo final setup */
+    set_bit(EDF_DONEINIT, &ed->ed_flags);
 
     return 0;
 }
 
+
 void new_thread(struct exec_domain *d,
                 unsigned long start_pc,
                 unsigned long start_stack,
index 60a8b74b752107eae6991637710fe464090a9aef..df728da1a7dc7248683bae60262ca6c0c3edc2de 100644 (file)
@@ -222,8 +222,19 @@ asmlinkage int do_int3(struct xen_regs *regs)
         DEBUGGER_trap_fatal(TRAP_int3, regs);
         show_registers(regs);
         panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n", smp_processor_id());
+    } 
+#ifdef XEN_UDB
+    else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) 
+    {
+        if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) {
+            while (ed == current)
+                __enter_scheduler();
+            domain_pause_by_systemcontroller(ed->domain);
+        }
+        
+        return 0;
     }
-
+#endif /* XEN_UDB */
     ti = current->arch.traps + 3;
     tb->flags = TBF_EXCEPTION;
     tb->cs    = ti->cs;
@@ -886,8 +897,8 @@ asmlinkage int math_state_restore(struct xen_regs *regs)
 asmlinkage int do_debug(struct xen_regs *regs)
 {
     unsigned long condition;
-    struct exec_domain *d = current;
-    struct trap_bounce *tb = &d->arch.trap_bounce;
+    struct exec_domain *ed = current;
+    struct trap_bounce *tb = &ed->arch.trap_bounce;
 
     DEBUGGER_trap_entry(TRAP_debug, regs);
 
@@ -895,7 +906,7 @@ asmlinkage int do_debug(struct xen_regs *regs)
 
     /* Mask out spurious debug traps due to lazy DR7 setting */
     if ( (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) &&
-         (d->arch.debugreg[7] == 0) )
+         (ed->arch.debugreg[7] == 0) )
     {
         __asm__("mov %0,%%db7" : : "r" (0UL));
         goto out;
@@ -912,14 +923,26 @@ asmlinkage int do_debug(struct xen_regs *regs)
          * breakpoint, which can't happen to us.
          */
         goto out;
-    }
+    } 
+#ifdef XEN_UDB
+    else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) 
+    {
+        regs->eflags &= ~EF_TF;
+        if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) {
+            while (ed == current)
+                __enter_scheduler();
+            domain_pause_by_systemcontroller(ed->domain);
+        }
 
+        goto out;
+    }    
+#endif /* XEN_UDB */
     /* Save debug status register where guest OS can peek at it */
-    d->arch.debugreg[6] = condition;
+    ed->arch.debugreg[6] = condition;
 
     tb->flags = TBF_EXCEPTION;
-    tb->cs    = d->arch.traps[1].cs;
-    tb->eip   = d->arch.traps[1].address;
+    tb->cs    = ed->arch.traps[1].cs;
+    tb->eip   = ed->arch.traps[1].address;
 
  out:
     return EXCRET_not_a_fault;
index 2bf6f1aaf6cdad51132d02570b4cf59230b8cd3d..75547d989c6df44a52c90ffed05a2971590d7091 100644 (file)
@@ -111,13 +111,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     switch ( op->cmd )
     {
 
-    case DOM0_BUILDDOMAIN:
+    case DOM0_SETDOMAININFO:
     {
-        struct domain *d = find_domain_by_id(op->u.builddomain.domain);
+        struct domain *d = find_domain_by_id(op->u.setdomaininfo.domain);
         ret = -ESRCH;
         if ( d != NULL )
         {
-            ret = final_setup_guest(d, &op->u.builddomain);
+            ret = set_info_guest(d, &op->u.setdomaininfo);
             put_domain(d);
         }
     }
index 50e3b85405cf7be9c15818dc87ed2802a56a08be..1b1edfe7f614c89c676982764bf3eb77a39b284b 100644 (file)
@@ -256,31 +256,34 @@ void domain_destruct(struct domain *d)
 
 
 /*
- * final_setup_guest is used for final setup and launching of domains other
- * than domain 0. ie. the domains that are being built by the userspace dom0
- * domain builder.
+ * set_info_guest is used for final setup, launching, and state modification 
+ * of domains other than domain 0. ie. the domains that are being built by 
+ * the userspace dom0 domain builder.
  */
-int final_setup_guest(struct domain *p, dom0_builddomain_t *builddomain)
+int set_info_guest(struct domain *p, dom0_setdomaininfo_t *setdomaininfo)
 {
     int rc = 0;
-    full_execution_context_t *c;
+    full_execution_context_t *c = NULL;
+    unsigned long vcpu = setdomaininfo->exec_domain;
+    struct exec_domain *ed; 
+
+    if ( (vcpu >= MAX_VIRT_CPUS) || ((ed = p->exec_domain[vcpu]) != NULL) )
+        return -EINVAL;
+    
+    if (test_bit(DF_CONSTRUCTED, &p->d_flags) && 
+        !test_bit(EDF_CTRLPAUSE, &ed->ed_flags))
+        return -EINVAL;
 
     if ( (c = xmalloc(full_execution_context_t)) == NULL )
         return -ENOMEM;
 
-    if ( test_bit(DF_CONSTRUCTED, &p->d_flags) )
-    {
-        rc = -EINVAL;
-        goto out;
-    }
-
-    if ( copy_from_user(c, builddomain->ctxt, sizeof(*c)) )
+    if ( copy_from_user(c, setdomaininfo->ctxt, sizeof(*c)) )
     {
         rc = -EFAULT;
         goto out;
     }
     
-    if ( (rc = arch_final_setup_guest(p->exec_domain[0],c)) != 0 )
+    if ( (rc = arch_set_info_guest(ed, c)) != 0 )
         goto out;
 
     set_bit(DF_CONSTRUCTED, &p->d_flags);
@@ -331,7 +334,7 @@ long do_boot_vcpu(unsigned long vcpu, full_execution_context_t *ctxt)
 
     sched_add_domain(ed);
 
-    if ( (rc = arch_final_setup_guest(ed, c)) != 0 ) {
+    if ( (rc = arch_set_info_guest(ed, c)) != 0 ) {
         sched_rem_domain(ed);
         goto out;
     }
index 6ba044300fa5dbdcdb39264a5d92ef22a32c7972..b60b435941f7f23c2fa4b17427a0227694ece129 100644 (file)
@@ -109,16 +109,16 @@ typedef struct {
     u64      cpu_time;                /* 40 */
 } PACKED dom0_getdomaininfo_t; /* 48 bytes */
 
-#define DOM0_BUILDDOMAIN      13
+#define DOM0_SETDOMAININFO      13
 typedef struct {
     /* IN variables. */
-    domid_t                 domain;   /*  0 */
-    u16                     __pad0;   /*  2 */
-    u32                     __pad1;   /*  4 */
+    domid_t                   domain;       /*  0 */
+    u16                       exec_domain;  /*  2 */
+    u32                       __pad0;       /*  4 */
     /* IN/OUT parameters */
-    full_execution_context_t *ctxt;   /*  8 */
+    full_execution_context_t *ctxt;         /*  8 */
     MEMORY_PADDING;
-} PACKED dom0_builddomain_t; /* 16 bytes */
+} PACKED dom0_setdomaininfo_t;              /* 16 bytes */
 
 #define DOM0_IOPL             14
 typedef struct {
@@ -426,7 +426,7 @@ typedef struct {
         dom0_getmemlist_t        getmemlist;
         dom0_schedctl_t          schedctl;
         dom0_adjustdom_t         adjustdom;
-        dom0_builddomain_t       builddomain;
+        dom0_setdomaininfo_t     setdomaininfo;
         dom0_getdomaininfo_t     getdomaininfo;
         dom0_getpageframeinfo_t  getpageframeinfo;
         dom0_iopl_t              iopl;
index 8db16e2512402ca3fceb370239f42e248c7d62f7..0115f7d0e52be4860a2d05b0a0ba8a70a76bdca3 100644 (file)
@@ -18,7 +18,7 @@ extern void arch_do_createdomain(struct exec_domain *ed);
 
 extern void arch_do_boot_vcpu(struct exec_domain *ed);
 
-extern int  arch_final_setup_guest(
+extern int  arch_set_info_guest(
     struct exec_domain *d, full_execution_context_t *c);
 
 extern void free_perdomain_pt(struct domain *d);
index 68fa4e90d4591eacbb745ae6e4b8cedfaa02a6c9..9a8746dcfdc0ea35b2e72785b6fcda517830e846 100644 (file)
@@ -220,7 +220,7 @@ extern int construct_dom0(
     unsigned long image_start, unsigned long image_len, 
     unsigned long initrd_start, unsigned long initrd_len,
     char *cmdline);
-extern int final_setup_guest(struct domain *d, dom0_builddomain_t *);
+extern int set_info_guest(struct domain *d, dom0_setdomaininfo_t *);
 
 struct domain *find_domain_by_id(domid_t dom);
 struct domain *find_last_domain(void);
@@ -317,6 +317,7 @@ extern struct domain *domain_list;
 #define EDF_RUNNING     12 /* Currently running on a CPU.                    */
 #define EDF_CPUPINNED   13 /* Disables auto-migration.                       */
 #define EDF_MIGRATED    14 /* Domain migrated between CPUs.                  */
+#define EDF_DONEINIT    15 /* Initialization completed    .                  */
 
 static inline int domain_runnable(struct exec_domain *d)
 {