From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kip Macy Subject: guest debug support patches Date: Fri, 11 Mar 2005 11:00:09 -0800 Message-ID: Reply-To: Kip Macy Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_1043_8990272.1110567609563" Sender: xen-devel-admin@lists.sourceforge.net Errors-To: xen-devel-admin@lists.sourceforge.net List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , List-Archive: To: xen-devel@lists.sourceforge.net, Keir Fraser , Ian.Pratt@cl.cam.ac.uk List-Id: xen-devel@lists.xenproject.org ------=_Part_1043_8990272.1110567609563 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 ------=_Part_1043_8990272.1110567609563 Content-Type: text/plain; name="patch1" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="patch1" # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/03/09 15:04:40-08:00 kmacy@curly.lab.netapp.com=20 # add debug support #=20 # 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 #=20 # tools/libxc/xc_ptrace.c # 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +324 -0 #=20 # 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 #=20 # 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 #=20 # xen/include/public/dom0_ops.h # 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +7 -7 # builddomain->setdomaininfo #=20 # 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 #=20 # xen/common/dom0_ops.c # 2005/03/09 15:00:37-08:00 kmacy@curly.lab.netapp.com +3 -3 # builddomain->setdomaininfo #=20 # 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/x= c_ptrace.c #=20 # xen/arch/x86/traps.c # 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +11 -1 # pause guest on int3 #=20 # 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 #=20 # xen/arch/ia64/domain.c # 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +1 -1 # update interface #=20 # tools/libxc/xc_vmx_build.c # 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +3 -3 # use setdomaininfo #=20 # tools/libxc/xc_plan9_build.c # 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +5 -4 # use setdomaininfo #=20 # tools/libxc/xc_linux_restore.c # 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +3 -3 # use setdomaininfo #=20 # tools/libxc/xc_linux_build.c # 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +4 -3 # use setdomaininfo call #=20 # tools/libxc/Makefile # 2005/03/09 15:00:36-08:00 kmacy@curly.lab.netapp.com +1 -0 # compile ptrace #=20 diff -Nru a/tools/libxc/Makefile b/tools/libxc/Makefile --- a/tools/libxc/Makefile=092005-03-11 10:38:24 -08:00 +++ b/tools/libxc/Makefile=092005-03-11 10:38:24 -08:00 @@ -28,6 +28,7 @@ SRCS +=3D xc_misc.c SRCS +=3D xc_physdev.c SRCS +=3D xc_private.c +SRCS +=3D xc_ptrace.c SRCS +=3D xc_rrobin.c SRCS +=3D xc_vmx_build.c =20 diff -Nru a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c=092005-03-11 10:38:24 -08:00 +++ b/tools/libxc/xc_linux_build.c=092005-03-11 10:38:24 -08:00 @@ -369,6 +369,7 @@ =20 op.cmd =3D DOM0_GETDOMAININFO; op.u.getdomaininfo.domain =3D (domid_t)domid; + launch_op.u.setdomaininfo.exec_domain =3D 0; op.u.getdomaininfo.exec_domain =3D 0; op.u.getdomaininfo.ctxt =3D ctxt; if ( (do_dom0_op(xc_handle, &op) < 0) ||=20 @@ -459,10 +460,10 @@ =20 memset( &launch_op, 0, sizeof(launch_op) ); =20 - launch_op.u.builddomain.domain =3D (domid_t)domid; - launch_op.u.builddomain.ctxt =3D ctxt; + launch_op.u.setdomaininfo.domain =3D (domid_t)domid; + launch_op.u.setdomaininfo.ctxt =3D ctxt; =20 - launch_op.cmd =3D DOM0_BUILDDOMAIN; + launch_op.cmd =3D DOM0_SETDOMAININFO; rc =3D do_dom0_op(xc_handle, &launch_op); =20 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=092005-03-11 10:38:24 -08:00 +++ b/tools/libxc/xc_linux_restore.c=092005-03-11 10:38:24 -08:00 @@ -631,9 +631,9 @@ =20 xcio_info(ioctxt, "Domain ready to be built.\n"); =20 - op.cmd =3D DOM0_BUILDDOMAIN; - op.u.builddomain.domain =3D (domid_t)dom; - op.u.builddomain.ctxt =3D &ctxt; + op.cmd =3D DOM0_SETDOMAININFO; + op.u.setdomaininfo.domain =3D (domid_t)dom; + op.u.setdomaininfo.ctxt =3D &ctxt; rc =3D do_dom0_op(xc_handle, &op); =20 if ( rc !=3D 0 ) diff -Nru a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c --- a/tools/libxc/xc_plan9_build.c=092005-03-11 10:38:24 -08:00 +++ b/tools/libxc/xc_plan9_build.c=092005-03-11 10:38:24 -08:00 @@ -533,10 +533,11 @@ =20 =09memset(&launch_op, 0, sizeof (launch_op)); =20 -=09launch_op.u.builddomain.domain =3D (domid_t) domid; -=09// launch_op.u.builddomain.num_vifs =3D 1; -=09launch_op.u.builddomain.ctxt =3D ctxt; -=09launch_op.cmd =3D DOM0_BUILDDOMAIN; +=09launch_op.u.setdomaininfo.domain =3D (domid_t) domid; +=09launch_op.u.setdomaininfo.exec_domain =3D 0; +=09// launch_op.u.setdomaininfo.num_vifs =3D 1; +=09launch_op.u.setdomaininfo.ctxt =3D ctxt; +=09launch_op.cmd =3D DOM0_SETDOMAININFO; =09rc =3D do_dom0_op(xc_handle, &launch_op); =20 =09fprintf(stderr, "RC is %d\n", rc); diff -Nru a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c --- /dev/null=09Wed Dec 31 16:00:00 196900 +++ b/tools/libxc/xc_ptrace.c=092005-03-11 10:38:24 -08:00 @@ -0,0 +1,324 @@ +#include +#include +#include "xc_private.h" +#include +#include + + +#define BSD_PAGE_MASK=09(PAGE_SIZE-1) +#define=09PG_FRAME=09(~((unsigned long)BSD_PAGE_MASK) +#define PDRSHIFT 22 +#define=09PSL_T=09=090x00000100=09/* trace enable bit */ + + +/* + * long =20 + * ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data= ); + */ + +long xc_ptrace(enum __ptrace_request request,=20 +=09 pid_t pid, void *addr, void *data); +int waitdomain(int domain, int *status, int options); + +char * ptrace_names[] =3D { + "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 */=20 + int xds; /* 28 */ + int xes; /* 32 */ +=09int xfs; /* 36 */ +=09int xgs; /* 40 */ +=09long orig_eax; /* 44 */ + long eip; /* 48 */ + int xcs; /* 52 */ + long eflags; /* 56 */ + long esp; /* 60 */ =20 +=09int xss; /* 64 */ +}; +#define printval(x) printf("%s =3D %lx\n", #x, (long)x); +#define SET_PT_REGS(pt, xc) \ +{ \ +pt.ebx =3D xc.ebx; \ +pt.ecx =3D xc.ecx; \ +pt.edx =3D xc.edx; \ +pt.esi =3D xc.esi; \ +pt.edi =3D xc.edi; \ +pt.ebp =3D xc.ebp; \ +pt.eax =3D xc.eax; \ +pt.eip =3D xc.eip; \ +pt.xcs =3D xc.cs; \ +pt.eflags =3D xc.eflags; \ +pt.esp =3D xc.esp; \ +pt.xss =3D xc.ss; \ +pt.xes =3D xc.es; \ +pt.xds =3D xc.ds; \ +pt.xfs =3D xc.fs; \ +pt.xgs =3D xc.gs; \ +} + +#define SET_XC_REGS(pt, xc) \ +{ \ +xc.ebx =3D pt->ebx; \ +xc.ecx =3D pt->ecx; \ +xc.edx =3D pt->edx; \ +xc.esi =3D pt->esi; \ +xc.edi =3D pt->edi; \ +xc.ebp =3D pt->ebp; \ +xc.eax =3D pt->eax; \ +xc.eip =3D pt->eip; \ +xc.cs =3D pt->xcs; \ +xc.eflags =3D pt->eflags; \ +xc.esp =3D pt->esp; \ +xc.ss =3D pt->xss; \ +xc.es =3D pt->xes; \ +xc.ds =3D pt->xds; \ +xc.fs =3D pt->xfs; \ +xc.gs =3D 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 =3D (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 !=3D cr3_phys)=20 + { +=09cr3_phys =3D cr3; +=09if (cr3_virt) +=09 munmap(cr3_virt, PAGE_SIZE); +=09if ((cr3_virt =3D xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, +=09=09=09=09=09 PROT_READ, +=09=09=09=09=09 cr3_phys >> PAGE_SHIFT)) =3D=3D NULL) +=09 goto error_out; + }=20 + pde =3D cr3_virt[vtopdi(va)]; + if (pde !=3D pde_phys)=20 + { +=09pde_phys =3D pde; +=09if (pde_virt) +=09 munmap(pde_virt, PAGE_SIZE); +=09if ((pde_virt =3D xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, +=09=09=09=09=09 PROT_READ, +=09=09=09=09=09 pde_phys >> PAGE_SHIFT)) =3D=3D NULL) +=09 goto error_out; + } + page =3D pde_virt[ +=09=09 vtopti(va) +]; + if (page !=3D page_phys)=20 + { +=09page_phys =3D page; +=09if (page_virt) +=09 munmap(page_virt, PAGE_SIZE); +=09if ((page_virt =3D xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, +=09=09=09=09=09 PROT_READ|PROT_WRITE, +=09=09=09=09=09 page_phys >> PAGE_SHIFT)) =3D=3D NULL) +=09 goto error_out; + }=09 + return (void *)(((unsigned long)page_virt) | (va &~ BSD_PAGE_MASK)); + + error_out: + return 0; +} + +int=20 +waitdomain(int domain, int *status, int options) +{ + dom0_op_t op; + int retval; + full_execution_context_t ctxt; + struct timespec ts; + ts.tv_sec =3D 0; + ts.tv_nsec =3D 10*1000*1000; + + if (!xc_handle) +=09if ((xc_handle =3D xc_interface_open()) < 0)=20 +=09{ +=09 printf("xc_interface_open failed\n"); +=09 return -1; +=09} + op.cmd =3D DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain =3D domain; + op.u.getdomaininfo.ctxt =3D &ctxt; + retry: + + retval =3D do_dom0_op(xc_handle, &op); + if (retval) +=09goto done; + =20 + *status =3D op.u.getdomaininfo.flags; + =20 + if (options & WNOHANG) +=09goto done; +=09 + + if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)) {=09 +=09nanosleep(&ts,NULL); +=09goto retry; + } + done: + return retval; + +} + +long +xc_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data= ) +{ + dom0_op_t op; + int status =3D 0; + xc_domaininfo_t info; + struct gdb_regs pt; + long retval =3D 0; + char *guest_va; + op.interface_version =3D DOM0_INTERFACE_VERSION; + =20 + if (!xc_handle) +=09if ((xc_handle =3D xc_interface_open()) < 0) +=09 return -1; +#if 0 + printf("%20s %d, %p, %p \n", ptrace_names[request], pid, addr, data); +#endif + switch (request) {=09 + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: +=09if ((guest_va =3D map_domain_va(pid, addr)) =3D=3D NULL) +=09 goto done; +=09memcpy(data, guest_va, 4); +=09break; + case PTRACE_POKETEXT: + case PTRACE_POKEDATA: +=09if ((guest_va =3D map_domain_va(pid, addr)) =3D=3D NULL) +=09 goto done; +=09memcpy(guest_va, data, 4); +=09break; + case PTRACE_GETREGS: + case PTRACE_GETFPREGS: + case PTRACE_GETFPXREGS: +=09/* XXX hard-coding UP */ +=09retval =3D xc_domain_getfullinfo(xc_handle, pid, 0, &info, &ctxt); +=09if (retval) +=09 goto done; +=09if (request =3D=3D PTRACE_GETREGS) { +=09=09SET_PT_REGS(pt, ctxt.cpu_ctxt);=20 +=09=09memcpy(data, &pt, sizeof(elf_gregset_t)); +=09} else if (request =3D=3D PTRACE_GETFPREGS) +=09 memcpy(data, &ctxt.fpu_ctxt, sizeof(elf_fpregset_t)); +=09else /*if (request =3D=3D PTRACE_GETFPXREGS)*/ +=09 memcpy(data, &ctxt.fpu_ctxt, sizeof(elf_fpxregset_t)); +=09cr3 =3D ctxt.pt_base; +=09regs_valid =3D 1; +=09break; + case PTRACE_SETREGS: +=09op.cmd =3D DOM0_SETDOMAININFO; +=09SET_XC_REGS(((struct gdb_regs *)data), ctxt.cpu_ctxt); +=09op.u.setdomaininfo.domain =3D pid; +=09/* XXX need to understand multiple exec_domains */ +=09op.u.setdomaininfo.exec_domain =3D 0; +=09op.u.setdomaininfo.ctxt =3D &ctxt; +=09retval =3D do_dom0_op(xc_handle, &op); +=09if (retval) +=09 goto done; + +=09break; + case PTRACE_ATTACH: +=09op.cmd =3D DOM0_GETDOMAININFO; +=09op.u.getdomaininfo.domain =3D pid; +=09op.u.getdomaininfo.exec_domain =3D 0; +=09op.u.getdomaininfo.ctxt =3D &ctxt; +=09retval =3D do_dom0_op(xc_handle, &op); +=09if (retval) { +=09 perror("dom0 op failed"); +=09 goto done; +=09} +=09if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) +=09 goto done; +=09printf("domain not currently paused\n"); +=09op.cmd =3D DOM0_PAUSEDOMAIN; +=09op.u.pausedomain.domain =3D pid; +=09retval =3D do_dom0_op(xc_handle, &op); +=09break; + case PTRACE_SINGLESTEP: +=09ctxt.cpu_ctxt.eflags |=3D PSL_T; + case PTRACE_CONT: + case PTRACE_DETACH: +=09regs_valid =3D 0; +=09op.cmd =3D DOM0_UNPAUSEDOMAIN; +=09op.u.unpausedomain.domain =3D pid > 0 ? pid : -pid; +=09retval =3D do_dom0_op(xc_handle, &op); +=09break; + case PTRACE_SETFPREGS: + case PTRACE_SETFPXREGS: + case PTRACE_PEEKUSER: + case PTRACE_POKEUSER: + case PTRACE_SYSCALL: + case PTRACE_KILL: +=09printf("unsupported xc_ptrace request %s\n", ptrace_names[request]); +=09/* XXX not yet supported */ +=09status =3D ENOSYS; +=09break; + case PTRACE_TRACEME: +=09printf("PTRACE_TRACEME is an invalid request under Xen\n"); +=09status =3D EINVAL; + } + =20 + if (status) { +=09errno =3D status; +=09retval =3D -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=092005-03-11 10:38:24 -08:00 +++ b/tools/libxc/xc_vmx_build.c=092005-03-11 10:38:24 -08:00 @@ -603,10 +603,10 @@ =20 memset( &launch_op, 0, sizeof(launch_op) ); =20 - launch_op.u.builddomain.domain =3D (domid_t)domid; - launch_op.u.builddomain.ctxt =3D ctxt; + launch_op.u.setdomaininfo.domain =3D (domid_t)domid; + launch_op.u.setdomaininfo.ctxt =3D ctxt; =20 - launch_op.cmd =3D DOM0_BUILDDOMAIN; + launch_op.cmd =3D DOM0_SETDOMAININFO; rc =3D do_dom0_op(xc_handle, &launch_op); return rc; =20 diff -Nru a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c --- a/xen/arch/ia64/domain.c=092005-03-11 10:38:24 -08:00 +++ b/xen/arch/ia64/domain.c=092005-03-11 10:38:24 -08:00 @@ -200,7 +200,7 @@ =09return; } =20 -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= ) { =09dummy(); =09return 1; diff -Nru a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c=092005-03-11 10:38:24 -08:00 +++ b/xen/arch/x86/domain.c=092005-03-11 10:38:24 -08:00 @@ -422,30 +422,15 @@ =20 =20 /* 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 =3D ed->domain; unsigned long phys_basetab; int i, rc; =20 - clear_bit(EDF_DONEFPUINIT, &ed->ed_flags); - if ( c->flags & ECF_I387_VALID ) - set_bit(EDF_DONEFPUINIT, &ed->ed_flags); - - ed->arch.flags &=3D ~TF_kernel_mode; - if ( c->flags & ECF_IN_KERNEL ) - ed->arch.flags |=3D 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 &=3D 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 automatica= lly. * If SS RPL or DPL differs from CS RPL then we'll #GP. @@ -455,11 +440,30 @@ ((ed->arch.user_ctxt.ss & 3) =3D=3D 0) ) return -EINVAL; =20 + memcpy(&ed->arch.user_ctxt, + &c->cpu_ctxt, + sizeof(ed->arch.user_ctxt)); + memcpy(&ed->arch.i387, &c->fpu_ctxt, sizeof(ed->arch.i387)); =20 - 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 &=3D ~TF_kernel_mode; + if ( c->flags & ECF_IN_KERNEL ) + ed->arch.flags |=3D TF_kernel_mode; + + /* Clear IOPL for unprivileged domains. */ + if (!IS_PRIV(d)) + ed->arch.user_ctxt.eflags &=3D 0xffffcfff; + + memcpy(ed->arch.traps, &c->trap_ctxt, sizeof(ed->arch.traps)); =20 @@ -505,9 +509,13 @@ #endif =20 update_pagetables(ed); + =20 + /* Don't redo final setup */ + set_bit(EDF_DONEINIT, &ed->ed_flags); =20 return 0; } + =20 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=092005-03-11 10:38:24 -08:00 +++ b/xen/arch/x86/traps.c=092005-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 =3D 3 (Int3)\n", smp_processor_id(= )); - } + }=20 + else if ( KERNEL_MODE(ed, regs) && ed->domain->id !=3D 0 )=20 + { + regs->eflags &=3D ~X86_EFLAGS_TF; + if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) { + while (ed =3D=3D current) + __enter_scheduler(); + domain_pause_by_systemcontroller(ed->domain); + } =20 + return 0; + } =20 ti =3D current->arch.traps + 3; tb->flags =3D TBF_EXCEPTION; tb->cs =3D ti->cs; diff -Nru a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c --- a/xen/common/dom0_ops.c=092005-03-11 10:38:24 -08:00 +++ b/xen/common/dom0_ops.c=092005-03-11 10:38:24 -08:00 @@ -111,13 +111,13 @@ switch ( op->cmd ) { =20 - case DOM0_BUILDDOMAIN: + case DOM0_SETDOMAININFO: { - struct domain *d =3D find_domain_by_id(op->u.builddomain.domain); + struct domain *d =3D find_domain_by_id(op->u.setdomaininfo.domain)= ; ret =3D -EINVAL; if ( d !=3D NULL ) { - ret =3D final_setup_guest(d, &op->u.builddomain); + ret =3D 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=092005-03-11 10:38:24 -08:00 +++ b/xen/common/domain.c=092005-03-11 10:38:24 -08:00 @@ -260,34 +260,36 @@ * than domain 0. ie. the domains that are being built by the userspace do= m0 * 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 =3D 0; full_execution_context_t *c; + struct exec_domain *ed =3D p->exec_domain[setdomain->exec_domain]; + =20 + if (ed =3D=3D NULL) + return -EINVAL; + + if (test_bit(DF_CONSTRUCTED, &p->d_flags) &&=20 + !test_bit(EDF_CTRLPAUSE, &ed->ed_flags)) + return -EINVAL; =20 if ( (c =3D xmalloc(full_execution_context_t)) =3D=3D NULL ) return -ENOMEM; =20 - if ( test_bit(DF_CONSTRUCTED, &p->d_flags) ) - { - rc =3D -EINVAL; - goto out; - } - - if ( copy_from_user(c, builddomain->ctxt, sizeof(*c)) ) + if ( copy_from_user(c, setdomain->ctxt, sizeof(*c)) ) { rc =3D -EFAULT; goto out; } - =20 - if ( (rc =3D arch_final_setup_guest(p->exec_domain[0],c)) !=3D 0 ) + + if ( (rc =3D arch_set_info_guest(p->exec_domain[setdomain->exec_domain= ],c)) !=3D 0 ) goto out; =20 /* Set up the shared info structure. */ update_dom_time(p); - + =20 set_bit(DF_CONSTRUCTED, &p->d_flags); - + =20 out: =20 if ( c !=3D NULL ) xfree(c); @@ -334,7 +336,7 @@ =20 sched_add_domain(ed); =20 - if ( (rc =3D arch_final_setup_guest(ed, c)) !=3D 0 ) { + if ( (rc =3D arch_set_info_guest(ed, c)) !=3D 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=092005-03-11 10:38:24 -08:00 +++ b/xen/include/public/dom0_ops.h=092005-03-11 10:38:24 -08:00 @@ -109,16 +109,16 @@ u64 cpu_time; /* 40 */ } PACKED dom0_getdomaininfo_t; /* 48 bytes */ =20 -#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 */ =20 #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=092005-03-11 10:38:24 -08:00 +++ b/xen/include/xen/domain.h=092005-03-11 10:38:24 -08:00 @@ -18,7 +18,7 @@ =20 extern void arch_do_boot_vcpu(struct exec_domain *ed); =20 -extern int arch_final_setup_guest( +extern int arch_set_info_guest( struct exec_domain *d, full_execution_context_t *c); =20 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=092005-03-11 10:38:24 -08:00 +++ b/xen/include/xen/sched.h=092005-03-11 10:38:24 -08:00 @@ -220,7 +220,7 @@ unsigned long image_start, unsigned long image_len,=20 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 *); =20 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 . = */ =20 static inline int domain_runnable(struct exec_domain *d) { ------=_Part_1043_8990272.1110567609563 Content-Type: text/plain; name="patch2" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="patch2" # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/03/10 20:28:04-08:00 kmacy@shemp.lab.netapp.com=20 # bug fixes to ptrace emulation #=20 # 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 #=20 # 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 #=20 # 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 #=20 # 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 #=20 # 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 #=20 diff -Nru a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c=092005-03-11 10:38:12 -08:00 +++ b/tools/libxc/xc_linux_build.c=092005-03-11 10:38:12 -08:00 @@ -369,7 +369,6 @@ =20 op.cmd =3D DOM0_GETDOMAININFO; op.u.getdomaininfo.domain =3D (domid_t)domid; - launch_op.u.setdomaininfo.exec_domain =3D 0; op.u.getdomaininfo.exec_domain =3D 0; op.u.getdomaininfo.ctxt =3D ctxt; if ( (do_dom0_op(xc_handle, &op) < 0) ||=20 @@ -461,6 +460,7 @@ memset( &launch_op, 0, sizeof(launch_op) ); =20 launch_op.u.setdomaininfo.domain =3D (domid_t)domid; + launch_op.u.setdomaininfo.exec_domain =3D 0; launch_op.u.setdomaininfo.ctxt =3D ctxt; =20 launch_op.cmd =3D DOM0_SETDOMAININFO; diff -Nru a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c=092005-03-11 10:38:12 -08:00 +++ b/tools/libxc/xc_ptrace.c=092005-03-11 10:38:12 -08:00 @@ -110,7 +110,7 @@ =20 =20 #define vtopdi(va) ((va) >> PDRSHIFT) -#define vtopti(va) (((va) >> PAGE_SHIFT) & PAGE_MASK) +#define vtopti(va) (((va) >> PAGE_SHIFT) & BSD_PAGE_MASK) =20 /* XXX application state */ =20 @@ -156,9 +156,7 @@ =09=09=09=09=09 pde_phys >> PAGE_SHIFT)) =3D=3D NULL) =09 goto error_out; } - page =3D pde_virt[ -=09=09 vtopti(va) -]; + page =3D pde_virt[vtopti(va)]; if (page !=3D page_phys)=20 { =09page_phys =3D page; @@ -169,7 +167,7 @@ =09=09=09=09=09 page_phys >> PAGE_SHIFT)) =3D=3D NULL) =09 goto error_out; }=09 - return (void *)(((unsigned long)page_virt) | (va &~ BSD_PAGE_MASK)); + return (void *)(((unsigned long)page_virt) | (va & BSD_PAGE_MASK)); =20 error_out: return 0; @@ -193,13 +191,15 @@ =09} op.cmd =3D DOM0_GETDOMAININFO; op.u.getdomaininfo.domain =3D domain; + op.u.getdomaininfo.exec_domain =3D 0; op.u.getdomaininfo.ctxt =3D &ctxt; retry: =20 retval =3D do_dom0_op(xc_handle, &op); - if (retval) + if (retval) { +=09printf("getdomaininfo failed\n"); =09goto done; - =20 + } *status =3D op.u.getdomaininfo.flags; =20 if (options & WNOHANG) @@ -223,35 +223,39 @@ xc_domaininfo_t info; struct gdb_regs pt; long retval =3D 0; - char *guest_va; + long *guest_va; + op.interface_version =3D DOM0_INTERFACE_VERSION; =20 if (!xc_handle) =09if ((xc_handle =3D xc_interface_open()) < 0) =09 return -1; -#if 0 +#if 0 printf("%20s %d, %p, %p \n", ptrace_names[request], pid, addr, data); #endif switch (request) {=09 case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: -=09if ((guest_va =3D map_domain_va(pid, addr)) =3D=3D NULL) -=09 goto done; -=09memcpy(data, guest_va, 4); -=09break; case PTRACE_POKETEXT: case PTRACE_POKEDATA: -=09if ((guest_va =3D map_domain_va(pid, addr)) =3D=3D NULL) +=09if ((guest_va =3D (unsigned long *)map_domain_va(pid, addr)) =3D=3D NUL= L) =09 goto done; -=09memcpy(guest_va, data, 4); + +=09if (request =3D=3D PTRACE_PEEKTEXT || request =3D=3D PTRACE_PEEKDATA) +=09 retval =3D *guest_va; +=09else +=09 *guest_va =3D (unsigned long)data; =09break; case PTRACE_GETREGS: case PTRACE_GETFPREGS: case PTRACE_GETFPXREGS: =09/* XXX hard-coding UP */ =09retval =3D xc_domain_getfullinfo(xc_handle, pid, 0, &info, &ctxt); -=09if (retval) + +=09if (retval) { +=09 printf("getfullinfo failed\n"); =09 goto done; +=09} =09if (request =3D=3D PTRACE_GETREGS) { =09=09SET_PT_REGS(pt, ctxt.cpu_ctxt);=20 =09=09memcpy(data, &pt, sizeof(elf_gregset_t)); @@ -284,8 +288,10 @@ =09 perror("dom0 op failed"); =09 goto done; =09} -=09if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) +=09if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) { +=09 printf("domain currently paused\n"); =09 goto done; +=09} =09printf("domain not currently paused\n"); =09op.cmd =3D DOM0_PAUSEDOMAIN; =09op.u.pausedomain.domain =3D pid; @@ -293,6 +299,15 @@ =09break; case PTRACE_SINGLESTEP: =09ctxt.cpu_ctxt.eflags |=3D PSL_T; +=09op.cmd =3D DOM0_SETDOMAININFO; +=09op.u.setdomaininfo.domain =3D pid; +=09op.u.setdomaininfo.exec_domain =3D 0; +=09op.u.setdomaininfo.ctxt =3D &ctxt; +=09retval =3D do_dom0_op(xc_handle, &op);=09 +=09if (retval) { +=09 perror("dom0 op failed"); +=09 goto done; +=09} case PTRACE_CONT: case PTRACE_DETACH: =09regs_valid =3D 0; @@ -306,7 +321,9 @@ case PTRACE_POKEUSER: case PTRACE_SYSCALL: case PTRACE_KILL: +#ifdef DEBUG =09printf("unsupported xc_ptrace request %s\n", ptrace_names[request]); +#endif =09/* XXX not yet supported */ =09status =3D ENOSYS; =09break; diff -Nru a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c=092005-03-11 10:38:12 -08:00 +++ b/xen/arch/x86/domain.c=092005-03-11 10:38:12 -08:00 @@ -431,6 +431,14 @@ unsigned long phys_basetab; int i, rc; =20 + 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 automatica= lly. @@ -440,14 +448,6 @@ if ( ((ed->arch.user_ctxt.cs & 3) =3D=3D 0) || ((ed->arch.user_ctxt.ss & 3) =3D=3D 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)); =20 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=092005-03-11 10:38:12 -08:00 +++ b/xen/arch/x86/traps.c=092005-03-11 10:38:12 -08:00 @@ -225,14 +225,13 @@ }=20 else if ( KERNEL_MODE(ed, regs) && ed->domain->id !=3D 0 )=20 { - regs->eflags &=3D ~X86_EFLAGS_TF; if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) { while (ed =3D=3D current) __enter_scheduler(); domain_pause_by_systemcontroller(ed->domain); } =20 - return 0; + goto out; } =20 ti =3D current->arch.traps + 3; tb->flags =3D TBF_EXCEPTION; @@ -241,6 +240,7 @@ if ( TI_GET_IF(ti) ) ed->vcpu_info->evtchn_upcall_mask =3D 1; =20 + out: return 0; } =20 @@ -694,8 +694,8 @@ asmlinkage int do_debug(struct xen_regs *regs) { unsigned long condition; - struct exec_domain *d =3D current; - struct trap_bounce *tb =3D &d->arch.trap_bounce; + struct exec_domain *ed =3D current; + struct trap_bounce *tb =3D &ed->arch.trap_bounce; =20 DEBUGGER_trap_entry(TRAP_debug, regs); =20 @@ -703,7 +703,7 @@ =20 /* Mask out spurious debug traps due to lazy DR7 setting */ if ( (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) && - (d->arch.debugreg[7] =3D=3D 0) ) + (ed->arch.debugreg[7] =3D=3D 0) ) { __asm__("mov %0,%%db7" : : "r" (0UL)); goto out; @@ -720,14 +720,25 @@ * breakpoint, which can't happen to us. */ goto out; - } + }=20 + else if ( KERNEL_MODE(ed, regs) && ed->domain->id !=3D 0 )=20 + { + regs->eflags &=3D ~EF_TF; + if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) { + while (ed =3D=3D current) + __enter_scheduler(); + domain_pause_by_systemcontroller(ed->domain); + } + + goto out; + } =20 =20 /* Save debug status register where guest OS can peek at it */ - d->arch.debugreg[6] =3D condition; + ed->arch.debugreg[6] =3D condition; =20 tb->flags =3D TBF_EXCEPTION; - tb->cs =3D d->arch.traps[1].cs; - tb->eip =3D d->arch.traps[1].address; + tb->cs =3D ed->arch.traps[1].cs; + tb->eip =3D ed->arch.traps[1].address; =20 out: return EXCRET_not_a_fault; ------=_Part_1043_8990272.1110567609563-- ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click