* guest debug support patches
@ 2005-03-11 19:00 Kip Macy
0 siblings, 0 replies; only message in thread
From: Kip Macy @ 2005-03-11 19:00 UTC (permalink / raw)
To: xen-devel, Keir Fraser, Ian.Pratt
[-- Attachment #1: Type: text/plain, Size: 1460 bytes --]
These two patches should really be one patch. However, when I try:
bk export -tpatch -r1.1294.1,1.1307,1.1308,1.1309,1.1310,1.1311
The output includes a large number of files that I haven't touched. My
guess is that there is a bug in the graph re-labelling in bk.
Thus patch1 is the output of:
bk export -tpatch -r1.1294.1.1
And patch2 is the output of:
bk export -tpatch -r1.1307,1.1308,1.1309,1.1310,1.1311
These patches have three real changes:
1) xen/arch/x86/traps.c in do_int3 and do_debug if the trap was hit in
kernel-mode on domain other than dom0 the domain is paused
2) builddomain is re-factored into setdomaininfo, the parts of what
was arch_final_setup_guest that should only be set once are skipped by
means of a new exec_domain flag EDF_DONEINIT
3) xc_ptrace.c implements the ptrace interface via dom0 ops
known limitations:
- Although the hypervisor-side code should work on x86_64, the
user-side xc_ptrace is currently strictly x86_32, fixing this is a
SMOP
- xc_ptrace assumes the guest is UP - I intend to fix this right after
I get 5.3 booting SMP as a guest - I would wait until this was fixed
were it not for the fact that the resolves can get annoying
- the patch doesn't include the gdbserver side support, I'm not sure
how best to handle this as most GDB maintainers move at a glacial pace
when it comes to incorporating outside patches
Comments and suggestions are welcome.
signed off by Kip Macy kmacy at fsmware.com
[-- Attachment #2: patch1 --]
[-- Type: text/plain, Size: 22873 bytes --]
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2005/03/09 15:04:40-08:00 kmacy@curly.lab.netapp.com
# add debug support
#
# BitKeeper/etc/logging_ok
# 2005/03/09 15:00:56-08:00 kmacy@curly.lab.netapp.com +1 -0
# Logging to logging@openlogging.org accepted
#
# tools/libxc/xc_ptrace.c
# 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +324 -0
#
# xen/include/xen/sched.h
# 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +2 -1
# final_setup_guest->set_info_guset
# add per ed init done flag
#
# xen/include/xen/domain.h
# 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +1 -1
# arch_final_setup_guest -> arch_set_info_guest
#
# xen/include/public/dom0_ops.h
# 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +7 -7
# builddomain->setdomaininfo
#
# xen/common/domain.c
# 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +15 -13
# final_setup_guest -> set_info_guest
#
# xen/common/dom0_ops.c
# 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +3 -3
# builddomain->setdomaininfo
#
# tools/libxc/xc_ptrace.c
# 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +0 -0
# BitKeeper file /t/niners/users/xen/050304/xen-unstable.bk/tools/libxc/xc_ptrace.c
#
# xen/arch/x86/traps.c
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +11 -1
# pause guest on int3
#
# xen/arch/x86/domain.c
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +27 -19
# arch_final_setup_guest -> arch_set_info_guest
#
# xen/arch/ia64/domain.c
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +1 -1
# update interface
#
# tools/libxc/xc_vmx_build.c
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +3 -3
# use setdomaininfo
#
# tools/libxc/xc_plan9_build.c
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +5 -4
# use setdomaininfo
#
# tools/libxc/xc_linux_restore.c
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +3 -3
# use setdomaininfo
#
# tools/libxc/xc_linux_build.c
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +4 -3
# use setdomaininfo call
#
# tools/libxc/Makefile
# 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +1 -0
# compile ptrace
#
diff -Nru a/tools/libxc/Makefile b/tools/libxc/Makefile
--- a/tools/libxc/Makefile 2005-03-11 10:38:24 -08:00
+++ b/tools/libxc/Makefile 2005-03-11 10:38:24 -08:00
@@ -28,6 +28,7 @@
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
diff -Nru a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c 2005-03-11 10:38:24 -08:00
+++ b/tools/libxc/xc_linux_build.c 2005-03-11 10:38:24 -08:00
@@ -369,6 +369,7 @@
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = (domid_t)domid;
+ launch_op.u.setdomaininfo.exec_domain = 0;
op.u.getdomaininfo.exec_domain = 0;
op.u.getdomaininfo.ctxt = ctxt;
if ( (do_dom0_op(xc_handle, &op) < 0) ||
@@ -459,10 +460,10 @@
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.ctxt = ctxt;
- launch_op.cmd = DOM0_BUILDDOMAIN;
+ launch_op.cmd = DOM0_SETDOMAININFO;
rc = do_dom0_op(xc_handle, &launch_op);
return rc;
diff -Nru a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c 2005-03-11 10:38:24 -08:00
+++ b/tools/libxc/xc_linux_restore.c 2005-03-11 10:38:24 -08:00
@@ -631,9 +631,9 @@
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.ctxt = &ctxt;
rc = do_dom0_op(xc_handle, &op);
if ( rc != 0 )
diff -Nru a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c
--- a/tools/libxc/xc_plan9_build.c 2005-03-11 10:38:24 -08:00
+++ b/tools/libxc/xc_plan9_build.c 2005-03-11 10:38:24 -08:00
@@ -533,10 +533,11 @@
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 -Nru a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/tools/libxc/xc_ptrace.c 2005-03-11 10:38:24 -08:00
@@ -0,0 +1,324 @@
+#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) & 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.ctxt = &ctxt;
+ retry:
+
+ retval = do_dom0_op(xc_handle, &op);
+ if (retval)
+ 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;
+ char *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:
+ if ((guest_va = map_domain_va(pid, addr)) == NULL)
+ goto done;
+ memcpy(data, guest_va, 4);
+ break;
+ case PTRACE_POKETEXT:
+ case PTRACE_POKEDATA:
+ if ((guest_va = map_domain_va(pid, addr)) == NULL)
+ goto done;
+ memcpy(guest_va, data, 4);
+ 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)
+ 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)
+ 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;
+ 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:
+ printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
+ /* 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;
+}
diff -Nru a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c 2005-03-11 10:38:24 -08:00
+++ b/tools/libxc/xc_vmx_build.c 2005-03-11 10:38:24 -08:00
@@ -603,10 +603,10 @@
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.ctxt = ctxt;
- launch_op.cmd = DOM0_BUILDDOMAIN;
+ launch_op.cmd = DOM0_SETDOMAININFO;
rc = do_dom0_op(xc_handle, &launch_op);
return rc;
diff -Nru a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c
--- a/xen/arch/ia64/domain.c 2005-03-11 10:38:24 -08:00
+++ b/xen/arch/ia64/domain.c 2005-03-11 10:38:24 -08:00
@@ -200,7 +200,7 @@
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;
diff -Nru a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c 2005-03-11 10:38:24 -08:00
+++ b/xen/arch/x86/domain.c 2005-03-11 10:38:24 -08:00
@@ -422,30 +422,15 @@
/* 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;
- clear_bit(EDF_DONEFPUINIT, &ed->ed_flags);
- if ( c->flags & ECF_I387_VALID )
- set_bit(EDF_DONEFPUINIT, &ed->ed_flags);
-
- ed->arch.flags &= ~TF_kernel_mode;
- if ( c->flags & ECF_IN_KERNEL )
- ed->arch.flags |= TF_kernel_mode;
-
- memcpy(&ed->arch.user_ctxt,
- &c->cpu_ctxt,
- sizeof(ed->arch.user_ctxt));
-
- /* Clear IOPL for unprivileged domains. */
- 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.
@@ -455,11 +440,30 @@
((ed->arch.user_ctxt.ss & 3) == 0) )
return -EINVAL;
+ memcpy(&ed->arch.user_ctxt,
+ &c->cpu_ctxt,
+ sizeof(ed->arch.user_ctxt));
+
memcpy(&ed->arch.i387,
&c->fpu_ctxt,
sizeof(ed->arch.i387));
- memcpy(ed->arch.traps,
+ if (test_bit(EDF_DONEINIT, &ed->ed_flags))
+ return 0;
+
+ clear_bit(EDF_DONEFPUINIT, &ed->ed_flags);
+ if ( c->flags & ECF_I387_VALID )
+ set_bit(EDF_DONEFPUINIT, &ed->ed_flags);
+
+ ed->arch.flags &= ~TF_kernel_mode;
+ if ( c->flags & ECF_IN_KERNEL )
+ ed->arch.flags |= TF_kernel_mode;
+
+ /* Clear IOPL for unprivileged domains. */
+ if (!IS_PRIV(d))
+ ed->arch.user_ctxt.eflags &= 0xffffcfff;
+
+ memcpy(ed->arch.traps,
&c->trap_ctxt,
sizeof(ed->arch.traps));
@@ -505,9 +509,13 @@
#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,
diff -Nru a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c 2005-03-11 10:38:24 -08:00
+++ b/xen/arch/x86/traps.c 2005-03-11 10:38:24 -08:00
@@ -221,8 +221,18 @@
DEBUGGER_trap_fatal(TRAP_int3, regs);
show_registers(regs);
panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n", smp_processor_id());
- }
+ }
+ else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 )
+ {
+ regs->eflags &= ~X86_EFLAGS_TF;
+ if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) {
+ while (ed == current)
+ __enter_scheduler();
+ domain_pause_by_systemcontroller(ed->domain);
+ }
+ return 0;
+ }
ti = current->arch.traps + 3;
tb->flags = TBF_EXCEPTION;
tb->cs = ti->cs;
diff -Nru a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c 2005-03-11 10:38:24 -08:00
+++ b/xen/common/dom0_ops.c 2005-03-11 10:38:24 -08:00
@@ -111,13 +111,13 @@
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 = -EINVAL;
if ( d != NULL )
{
- ret = final_setup_guest(d, &op->u.builddomain);
+ ret = set_info_guest(d, &op->u.setdomaininfo);
put_domain(d);
}
}
diff -Nru a/xen/common/domain.c b/xen/common/domain.c
--- a/xen/common/domain.c 2005-03-11 10:38:24 -08:00
+++ b/xen/common/domain.c 2005-03-11 10:38:24 -08:00
@@ -260,34 +260,36 @@
* 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 *setdomain)
{
int rc = 0;
full_execution_context_t *c;
+ struct exec_domain *ed = p->exec_domain[setdomain->exec_domain];
+
+ if (ed == 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, setdomain->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(p->exec_domain[setdomain->exec_domain],c)) != 0 )
goto out;
/* Set up the shared info structure. */
update_dom_time(p);
-
+
set_bit(DF_CONSTRUCTED, &p->d_flags);
-
+
out:
if ( c != NULL )
xfree(c);
@@ -334,7 +336,7 @@
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;
}
diff -Nru a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h 2005-03-11 10:38:24 -08:00
+++ b/xen/include/public/dom0_ops.h 2005-03-11 10:38:24 -08:00
@@ -109,16 +109,16 @@
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 @@
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;
diff -Nru a/xen/include/xen/domain.h b/xen/include/xen/domain.h
--- a/xen/include/xen/domain.h 2005-03-11 10:38:24 -08:00
+++ b/xen/include/xen/domain.h 2005-03-11 10:38:24 -08:00
@@ -18,7 +18,7 @@
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);
diff -Nru a/xen/include/xen/sched.h b/xen/include/xen/sched.h
--- a/xen/include/xen/sched.h 2005-03-11 10:38:24 -08:00
+++ b/xen/include/xen/sched.h 2005-03-11 10:38:24 -08:00
@@ -220,7 +220,7 @@
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);
@@ -316,6 +316,7 @@
#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)
{
[-- Attachment #3: patch2 --]
[-- Type: text/plain, Size: 8813 bytes --]
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2005/03/10 20:28:04-08:00 kmacy@shemp.lab.netapp.com
# bug fixes to ptrace emulation
#
# BitKeeper/etc/logging_ok
# 2005/03/10 20:28:04-08:00 kmacy@shemp.lab.netapp.com +1 -0
# Logging to logging@openlogging.org accepted
#
# xen/arch/x86/traps.c
# 2005/03/10 20:27:44-08:00 kmacy@shemp.lab.netapp.com +20 -9
# handle trace trap as well as int3
#
# xen/arch/x86/domain.c
# 2005/03/10 20:27:44-08:00 kmacy@shemp.lab.netapp.com +8 -8
# move register copying above segment check
#
# tools/libxc/xc_ptrace.c
# 2005/03/10 20:27:44-08:00 kmacy@shemp.lab.netapp.com +34 -17
# fix mask handling of pts
# fix single-stepping
# simplify PEEK and POKE operations
#
# tools/libxc/xc_linux_build.c
# 2005/03/10 20:27:44-08:00 kmacy@shemp.lab.netapp.com +1 -1
# move setting of exec_domain to more sensible location
#
diff -Nru a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c 2005-03-11 10:38:12 -08:00
+++ b/tools/libxc/xc_linux_build.c 2005-03-11 10:38:12 -08:00
@@ -369,7 +369,6 @@
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = (domid_t)domid;
- launch_op.u.setdomaininfo.exec_domain = 0;
op.u.getdomaininfo.exec_domain = 0;
op.u.getdomaininfo.ctxt = ctxt;
if ( (do_dom0_op(xc_handle, &op) < 0) ||
@@ -461,6 +460,7 @@
memset( &launch_op, 0, sizeof(launch_op) );
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_SETDOMAININFO;
diff -Nru a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c 2005-03-11 10:38:12 -08:00
+++ b/tools/libxc/xc_ptrace.c 2005-03-11 10:38:12 -08:00
@@ -110,7 +110,7 @@
#define vtopdi(va) ((va) >> PDRSHIFT)
-#define vtopti(va) (((va) >> PAGE_SHIFT) & PAGE_MASK)
+#define vtopti(va) (((va) >> PAGE_SHIFT) & BSD_PAGE_MASK)
/* XXX application state */
@@ -156,9 +156,7 @@
pde_phys >> PAGE_SHIFT)) == NULL)
goto error_out;
}
- page = pde_virt[
- vtopti(va)
-];
+ page = pde_virt[vtopti(va)];
if (page != page_phys)
{
page_phys = page;
@@ -169,7 +167,7 @@
page_phys >> PAGE_SHIFT)) == NULL)
goto error_out;
}
- return (void *)(((unsigned long)page_virt) | (va &~ BSD_PAGE_MASK));
+ return (void *)(((unsigned long)page_virt) | (va & BSD_PAGE_MASK));
error_out:
return 0;
@@ -193,13 +191,15 @@
}
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)
+ if (retval) {
+ printf("getdomaininfo failed\n");
goto done;
-
+ }
*status = op.u.getdomaininfo.flags;
if (options & WNOHANG)
@@ -223,35 +223,39 @@
xc_domaininfo_t info;
struct gdb_regs pt;
long retval = 0;
- char *guest_va;
+ long *guest_va;
+
op.interface_version = DOM0_INTERFACE_VERSION;
if (!xc_handle)
if ((xc_handle = xc_interface_open()) < 0)
return -1;
-#if 0
+#if 0
printf("%20s %d, %p, %p \n", ptrace_names[request], pid, addr, data);
#endif
switch (request) {
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
- if ((guest_va = map_domain_va(pid, addr)) == NULL)
- goto done;
- memcpy(data, guest_va, 4);
- break;
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
- if ((guest_va = map_domain_va(pid, addr)) == NULL)
+ if ((guest_va = (unsigned long *)map_domain_va(pid, addr)) == NULL)
goto done;
- memcpy(guest_va, data, 4);
+
+ 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)
+
+ 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));
@@ -284,8 +288,10 @@
perror("dom0 op failed");
goto done;
}
- if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)
+ 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;
@@ -293,6 +299,15 @@
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;
@@ -306,7 +321,9 @@
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;
diff -Nru a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c 2005-03-11 10:38:12 -08:00
+++ b/xen/arch/x86/domain.c 2005-03-11 10:38:12 -08:00
@@ -431,6 +431,14 @@
unsigned long phys_basetab;
int i, rc;
+ memcpy(&ed->arch.user_ctxt,
+ &c->cpu_ctxt,
+ sizeof(ed->arch.user_ctxt));
+
+ memcpy(&ed->arch.i387,
+ &c->fpu_ctxt,
+ sizeof(ed->arch.i387));
+
/*
* 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.
@@ -440,14 +448,6 @@
if ( ((ed->arch.user_ctxt.cs & 3) == 0) ||
((ed->arch.user_ctxt.ss & 3) == 0) )
return -EINVAL;
-
- memcpy(&ed->arch.user_ctxt,
- &c->cpu_ctxt,
- sizeof(ed->arch.user_ctxt));
-
- memcpy(&ed->arch.i387,
- &c->fpu_ctxt,
- sizeof(ed->arch.i387));
if (test_bit(EDF_DONEINIT, &ed->ed_flags))
return 0;
diff -Nru a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c 2005-03-11 10:38:12 -08:00
+++ b/xen/arch/x86/traps.c 2005-03-11 10:38:12 -08:00
@@ -225,14 +225,13 @@
}
else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 )
{
- regs->eflags &= ~X86_EFLAGS_TF;
if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) {
while (ed == current)
__enter_scheduler();
domain_pause_by_systemcontroller(ed->domain);
}
- return 0;
+ goto out;
}
ti = current->arch.traps + 3;
tb->flags = TBF_EXCEPTION;
@@ -241,6 +240,7 @@
if ( TI_GET_IF(ti) )
ed->vcpu_info->evtchn_upcall_mask = 1;
+ out:
return 0;
}
@@ -694,8 +694,8 @@
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);
@@ -703,7 +703,7 @@
/* 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;
@@ -720,14 +720,25 @@
* breakpoint, which can't happen to us.
*/
goto out;
- }
+ }
+ 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;
+ }
/* 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;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2005-03-11 19:00 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-11 19:00 guest debug support patches Kip Macy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.