[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1 of 2] libxc: remove xc_ptrace
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxx> # Date 1282550554 -3600 # Node ID 5922a25d30392cc88cae267ec66939e6fc05e36d # Parent 81503caeb439505f671fca29aa012c3f735f4e2f libxc: remove xc_ptrace It has been unused since 21732:eb34666befcc. There was no response to my RFC regarding its removal http://marc.info/?l=xen-devel&m=128170404422822 and unfortunately we have not been able to trace down all copyright holders of this code for the purposes of relicensing libxc. The code will be available in mercurial if we need to retrieve it in the future. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> diff -r 81503caeb439 -r 5922a25d3039 tools/libxc/Makefile --- a/tools/libxc/Makefile Sun Aug 22 09:53:51 2010 +0100 +++ b/tools/libxc/Makefile Mon Aug 23 09:02:34 2010 +0100 @@ -32,7 +32,6 @@ CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c -#CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c diff -r 81503caeb439 -r 5922a25d3039 tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Sun Aug 22 09:53:51 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,475 +0,0 @@ -#include <sys/ptrace.h> -#include <sys/wait.h> -#include <time.h> - -#include "xc_private.h" -#include "xg_private.h" -#include "xc_ptrace.h" - -#ifdef DEBUG -static 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", -}; -#endif - -static int current_domid = -1; -static int current_isfile; -static int current_is_hvm; - -static uint64_t online_cpumap; -static uint64_t regs_valid; -static unsigned int nr_vcpu_ids; -static vcpu_guest_context_any_t *ctxt; - -#define FOREACH_CPU(cpumap, i) for ( cpumap = online_cpumap; (i = xc_ffs64(cpumap)); cpumap &= ~(1 << (index - 1)) ) - -static int -fetch_regs(xc_interface *xch, int cpu, int *online) -{ - xc_vcpuinfo_t info; - int retval = 0; - - if (online) - *online = 0; - if ( !(regs_valid & (1 << cpu)) ) - { - retval = xc_vcpu_getcontext(xch, current_domid, - cpu, &ctxt[cpu]); - if ( retval ) - goto done; - regs_valid |= (1 << cpu); - - } - if ( online == NULL ) - goto done; - - retval = xc_vcpu_getinfo(xch, current_domid, cpu, &info); - *online = info.online; - - done: - return retval; -} - -static struct thr_ev_handlers { - thr_ev_handler_t td_create; - thr_ev_handler_t td_death; -} handlers; - -void -xc_register_event_handler(thr_ev_handler_t h, - td_event_e e) -{ - switch (e) { - case TD_CREATE: - handlers.td_create = h; - break; - case TD_DEATH: - handlers.td_death = h; - break; - default: - abort(); /* XXX */ - } -} - -static inline int -paging_enabled(vcpu_guest_context_any_t *v) -{ - unsigned long cr0 = v->c.ctrlreg[0]; - return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG); -} - -vcpu_guest_context_any_t *xc_ptrace_get_vcpu_ctxt(xc_interface *xch, - unsigned int nr_cpus) -{ - if (nr_cpus > nr_vcpu_ids) { - vcpu_guest_context_any_t *new; - - new = realloc(ctxt, nr_cpus * sizeof(*ctxt)); - if (!new) - return NULL; - ctxt = new; - nr_vcpu_ids = nr_cpus; - } - - return ctxt; -} - -/* - * Fetch registers for all online cpus and set the cpumap - * to indicate which cpus are online - * - */ - -static int -get_online_cpumap(xc_interface *xch, struct xen_domctl_getdomaininfo *d, - uint64_t *cpumap) -{ - int i, online; - - if (!xc_ptrace_get_vcpu_ctxt(xch, d->max_vcpu_id + 1)) - return -ENOMEM; - - *cpumap = 0; - for (i = 0; i <= d->max_vcpu_id; i++) { - fetch_regs(xch, i, &online); - if (online) - *cpumap |= (1 << i); - } - - return (*cpumap == 0) ? -1 : 0; -} - -/* - * Notify GDB of any vcpus that have come online or gone offline - * update online_cpumap - * - */ - -static void -online_vcpus_changed(xc_interface *xch, uint64_t cpumap) -{ - uint64_t changed_cpumap = cpumap ^ online_cpumap; - int index; - - while ( (index = xc_ffs64(changed_cpumap)) ) { - if ( cpumap & (1 << (index - 1)) ) - { - if (handlers.td_create) handlers.td_create(index - 1); - } else { - IPRINTF("thread death: %d\n", index - 1); - if (handlers.td_death) handlers.td_death(index - 1); - } - changed_cpumap &= ~(1 << (index - 1)); - } - online_cpumap = cpumap; - -} - - -static void * -map_domain_va( - xc_interface *xch, - int cpu, - void *guest_va, - int perm) -{ - unsigned long va = (unsigned long)guest_va; - unsigned long mfn; - void *map; - - /* cross page boundary */ - if ( (va & ~PAGE_MASK) + sizeof(long) > PAGE_SIZE ) - return NULL; - - mfn = xc_translate_foreign_address(xch, current_domid, cpu, va); - if ( mfn == 0 ) - return NULL; - - map = xc_map_foreign_range(xch, current_domid, PAGE_SIZE, - perm, mfn); - if (map == NULL) - return NULL; - - /* - * Due to the use of API fallback code in libxc, errno may - * be clobberred during successful operations. Since the caller - * of xc_ptrace is depending on errno for return status, clear - * errno here. - */ - errno = 0; - return map + (va & ~PAGE_MASK); -} - -static void -unmap_domain_va(void *guest_va) -{ - munmap((void *)((unsigned long)guest_va & PAGE_MASK), PAGE_SIZE); -} - -int control_c_pressed_flag = 0; - -static int -__xc_waitdomain( - xc_interface *xch, - int domain, - int *status, - int options) -{ - DECLARE_DOMCTL; - int retval; - struct timespec ts; - uint64_t cpumap; - - ts.tv_sec = 0; - ts.tv_nsec = 10*1000*1000; - - domctl.cmd = XEN_DOMCTL_getdomaininfo; - domctl.domain = domain; - - retry: - retval = do_domctl(xch, &domctl); - if ( retval || (domctl.domain != domain) ) - { - IPRINTF("getdomaininfo failed\n"); - goto done; - } - *status = domctl.u.getdomaininfo.flags; - - if ( options & WNOHANG ) - goto done; - - if (control_c_pressed_flag) { - xc_domain_pause(xch, domain); - control_c_pressed_flag = 0; - goto done; - } - - if ( !(domctl.u.getdomaininfo.flags & XEN_DOMINF_paused) ) - { - nanosleep(&ts,NULL); - goto retry; - } - done: - if (get_online_cpumap(xch, &domctl.u.getdomaininfo, &cpumap)) - IPRINTF("get_online_cpumap failed\n"); - if (online_cpumap != cpumap) - online_vcpus_changed(xch, cpumap); - return retval; - -} - - -long -xc_ptrace( - xc_interface *xch, - enum __ptrace_request request, - uint32_t domid_tid, - long eaddr, - long edata) -{ - DECLARE_DOMCTL; - struct gdb_regs pt; - long retval = 0; - unsigned long *guest_va; - uint64_t cpumap; - int cpu, index; - void *addr = (char *)eaddr; - void *data = (char *)edata; - - cpu = (request != PTRACE_ATTACH) ? domid_tid : 0; - - switch ( request ) - { - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: - if (current_isfile) - guest_va = (unsigned long *)map_domain_va_core( - xch, current_domid, cpu, addr); - else - guest_va = (unsigned long *)map_domain_va( - xch, cpu, addr, PROT_READ); - if ( guest_va == NULL ) - goto out_error; - retval = *guest_va; - if (!current_isfile) - unmap_domain_va(guest_va); - break; - - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - /* XXX assume that all CPUs have the same address space */ - if (current_isfile) - guest_va = (unsigned long *)map_domain_va_core( - xch, current_domid, cpu, addr); - else - guest_va = (unsigned long *)map_domain_va( - xch, cpu, addr, PROT_READ|PROT_WRITE); - if ( guest_va == NULL ) - goto out_error; - *guest_va = edata; - if (!current_isfile) - unmap_domain_va(guest_va); - break; - - case PTRACE_GETREGS: - if (!current_isfile && fetch_regs(xch, cpu, NULL)) - goto out_error; - SET_PT_REGS(pt, ctxt[cpu].c.user_regs); - memcpy(data, &pt, sizeof(struct gdb_regs)); - break; - - case PTRACE_GETFPREGS: - if (!current_isfile && fetch_regs(xch, cpu, NULL)) - goto out_error; - memcpy(data, &ctxt[cpu].c.fpu_ctxt, sizeof (elf_fpregset_t)); - break; - - case PTRACE_GETFPXREGS: - if (!current_isfile && fetch_regs(xch, cpu, NULL)) - goto out_error; - memcpy(data, &ctxt[cpu].c.fpu_ctxt, sizeof(ctxt[cpu].c.fpu_ctxt)); - break; - - case PTRACE_SETREGS: - if (current_isfile) - goto out_unsupported; /* XXX not yet supported */ - SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].c.user_regs); - if ((retval = xc_vcpu_setcontext(xch, current_domid, cpu, - &ctxt[cpu]))) - goto out_error_domctl; - break; - - case PTRACE_SINGLESTEP: - if (current_isfile) - goto out_unsupported; /* XXX not yet supported */ - /* XXX we can still have problems if the user switches threads - * during single-stepping - but that just seems retarded - */ - /* Try to enalbe Monitor Trap Flag for HVM, and fall back to TF - * if no MTF support - */ - if ( !current_is_hvm || - xc_domain_debug_control(xch, - current_domid, - XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON, - cpu) ) - { - ctxt[cpu].c.user_regs.eflags |= PSL_T; - if ((retval = xc_vcpu_setcontext(xch, current_domid, cpu, - &ctxt[cpu]))) - goto out_error_domctl; - } - /* FALLTHROUGH */ - - case PTRACE_CONT: - case PTRACE_DETACH: - if (current_isfile) - goto out_unsupported; /* XXX not yet supported */ - if ( request != PTRACE_SINGLESTEP ) - { - FOREACH_CPU(cpumap, index) { - cpu = index - 1; - if ( !current_is_hvm || - xc_domain_debug_control(xch, - current_domid, - XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF, - cpu) ) - { - if (fetch_regs(xch, cpu, NULL)) - goto out_error; - /* Clear trace flag */ - if ( ctxt[cpu].c.user_regs.eflags & PSL_T ) - { - ctxt[cpu].c.user_regs.eflags &= ~PSL_T; - if ((retval = xc_vcpu_setcontext(xch, current_domid, - cpu, &ctxt[cpu]))) - goto out_error_domctl; - } - } - } - } - if ( request == PTRACE_DETACH ) - { - if ((retval = xc_domain_setdebugging(xch, current_domid, 0))) - goto out_error_domctl; - } - regs_valid = 0; - if ((retval = xc_domain_unpause(xch, current_domid > 0 ? - current_domid : -current_domid))) - goto out_error_domctl; - break; - - case PTRACE_ATTACH: - current_domid = domid_tid; - current_isfile = (int)edata; - if (current_isfile) - break; - domctl.cmd = XEN_DOMCTL_getdomaininfo; - domctl.domain = current_domid; - retval = do_domctl(xch, &domctl); - if ( retval || (domctl.domain != current_domid) ) - goto out_error_domctl; - if ( domctl.u.getdomaininfo.flags & XEN_DOMINF_paused ) - IPRINTF("domain currently paused\n"); - else if ((retval = xc_domain_pause(xch, current_domid))) - goto out_error_domctl; - current_is_hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest); - if ((retval = xc_domain_setdebugging(xch, current_domid, 1))) - goto out_error_domctl; - - if (get_online_cpumap(xch, &domctl.u.getdomaininfo, &cpumap)) - IPRINTF("get_online_cpumap failed\n"); - if (online_cpumap != cpumap) - online_vcpus_changed(xch, cpumap); - break; - - case PTRACE_TRACEME: - IPRINTF("PTRACE_TRACEME is an invalid request under Xen\n"); - goto out_error; - - default: - goto out_unsupported; /* XXX not yet supported */ - } - - return retval; - - out_error_domctl: - PERROR("domctl failed"); - out_error: - errno = EINVAL; - return retval; - - out_unsupported: -#ifdef DEBUG - IPRINTF("unsupported xc_ptrace request %s\n", ptrace_names[request]); -#endif - errno = ENOSYS; - return -1; - -} - -int -xc_waitdomain( - xc_interface *xch, - int domain, - int *status, - int options) -{ - if (current_isfile) - return xc_waitdomain_core(xch, domain, status, options); - return __xc_waitdomain(xch, domain, status, options); -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff -r 81503caeb439 -r 5922a25d3039 tools/libxc/xc_ptrace.h --- a/tools/libxc/xc_ptrace.h Sun Aug 22 09:53:51 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -#error xc_ptrace is disabled. - -#ifndef XC_PTRACE_ -#define XC_PTRACE_ - -#define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */ -#define X86_CR0_PG 0x80000000 /* Paging (RW) */ -#define BSD_PAGE_MASK (PAGE_SIZE-1) -#define PSL_T 0x00000100 /* trace enable bit */ - -#ifdef __x86_64__ -struct gdb_regs -{ - unsigned long r15; - unsigned long r14; - unsigned long r13; - unsigned long r12; - unsigned long rbp; - unsigned long rbx; - unsigned long r11; - unsigned long r10; - unsigned long r9; - unsigned long r8; - unsigned long rax; - unsigned long rcx; - unsigned long rdx; - unsigned long rsi; - unsigned long rdi; - unsigned long orig_rax; - unsigned long rip; - unsigned long xcs; - unsigned long rflags; - unsigned long rsp; - unsigned long xss; - unsigned long fs_base; - unsigned long gs_base; - unsigned long xds; - unsigned long xes; - unsigned long xfs; - unsigned long xgs; -}; - -#define SET_PT_REGS(pt, xc) \ -{ \ - pt.r8 = xc.r8; \ - pt.r9 = xc.r9; \ - pt.r10 = xc.r10; \ - pt.r11 = xc.r11; \ - pt.r12 = xc.r12; \ - pt.r13 = xc.r13; \ - pt.r14 = xc.r14; \ - pt.r15 = xc.r15; \ - pt.rbx = xc.rbx; \ - pt.rcx = xc.rcx; \ - pt.rdx = xc.rdx; \ - pt.rsi = xc.rsi; \ - pt.rdi = xc.rdi; \ - pt.rbp = xc.rbp; \ - pt.rax = xc.rax; \ - pt.rip = xc.rip; \ - pt.xcs = xc.cs; \ - pt.rflags = xc.rflags; \ - pt.rsp = xc.rsp; \ - 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.r8 = pt->r8; \ - xc.r9 = pt->r9; \ - xc.r10 = pt->r10; \ - xc.r11 = pt->r11; \ - xc.r12 = pt->r12; \ - xc.r13 = pt->r13; \ - xc.r14 = pt->r14; \ - xc.r15 = pt->r15; \ - xc.rbx = pt->rbx; \ - xc.rcx = pt->rcx; \ - xc.rdx = pt->rdx; \ - xc.rsi = pt->rsi; \ - xc.rdi = pt->rdi; \ - xc.rbp = pt->rbp; \ - xc.rax = pt->rax; \ - xc.rip = pt->rip; \ - xc.cs = pt->xcs; \ - xc.rflags = pt->rflags & 0xffffffff; \ - xc.rsp = pt->rsp; \ - xc.ss = pt->xss; \ - xc.es = pt->xes; \ - xc.ds = pt->xds; \ - xc.fs = pt->xfs; \ - xc.gs = pt->xgs; \ -} - -#elif __i386__ - -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 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; \ -} -#endif - -void *map_domain_va_core(xc_interface *xch, - unsigned long domfd, int cpu, void *guest_va); -int xc_waitdomain_core(xc_interface *xch, - int domain, int *status, int options); -vcpu_guest_context_any_t *xc_ptrace_get_vcpu_ctxt(xc_interface *xch, - unsigned int nr_cpus); - - -#endif /* XC_PTRACE */ diff -r 81503caeb439 -r 5922a25d3039 tools/libxc/xc_ptrace_core.c --- a/tools/libxc/xc_ptrace_core.c Sun Aug 22 09:53:51 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,707 +0,0 @@ -/* - * New elf format support. - * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp> - * VA Linux Systems Japan K.K. - */ - -#include <sys/ptrace.h> -#include <sys/wait.h> -#include "xc_private.h" -#include "xg_private.h" -#include "xc_ptrace.h" -#include <time.h> -#include <inttypes.h> - -static unsigned int max_nr_vcpus; -static unsigned long *cr3; -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; - -static vcpu_guest_context_t * -ptrace_core_get_vcpu_ctxt(xc_interface *xch, unsigned int nr_vcpus) -{ - if (nr_vcpus > max_nr_vcpus) { - void *new; - -#define REALLOC(what) \ - new = realloc(what, nr_vcpus * sizeof(*what)); \ - if (!new) \ - return NULL; \ - memset(what + max_nr_vcpus, 0, \ - (nr_vcpus - max_nr_vcpus) * sizeof(*what)); \ - what = new - - REALLOC(cr3); - REALLOC(cr3_phys); - REALLOC(cr3_virt); - REALLOC(pde_phys); - REALLOC(pde_virt); - REALLOC(page_phys); - REALLOC(page_virt); - -#undef REALLOC - max_nr_vcpus = nr_vcpus; - } - - return &xc_ptrace_get_vcpu_ctxt(xch, nr_vcpus)->c; -} - -/* Leave the code for the old format as is. */ -/* --- compatible layer for old format ------------------------------------- */ -/* XXX application state */ - -static int current_is_hvm_compat = 0; -static long nr_pages_compat = 0; -static unsigned long *p2m_array_compat = NULL; -static unsigned long *m2p_array_compat = NULL; -static unsigned long pages_offset_compat; - -/* --------------------- */ - -static unsigned long -map_mtop_offset_compat(unsigned long ma) -{ - return pages_offset_compat + (m2p_array_compat[ma >> PAGE_SHIFT] << PAGE_SHIFT); - return 0; -} - - -static void * -map_domain_va_core_compat(xc_interface *xch, - unsigned long domfd, int cpu, void *guest_va) -{ - unsigned long pde, page; - unsigned long va = (unsigned long)guest_va; - void *v; - - if (cr3[cpu] != cr3_phys[cpu]) - { - cr3_phys[cpu] = cr3[cpu]; - if (cr3_virt[cpu]) - munmap(cr3_virt[cpu], PAGE_SIZE); - v = mmap( - NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, - map_mtop_offset_compat(xen_cr3_to_pfn(cr3_phys[cpu]))); - if (v == MAP_FAILED) - { - PERROR("mmap failed"); - return NULL; - } - cr3_virt[cpu] = v; - } - if ((pde = cr3_virt[cpu][l2_table_offset_i386(va)]) == 0) /* logical address */ - return NULL; - if (current_is_hvm_compat) - pde = p2m_array_compat[pde >> PAGE_SHIFT] << PAGE_SHIFT; - if (pde != pde_phys[cpu]) - { - pde_phys[cpu] = pde; - if (pde_virt[cpu]) - munmap(pde_virt[cpu], PAGE_SIZE); - v = mmap( - NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, - map_mtop_offset_compat(pde_phys[cpu])); - if (v == MAP_FAILED) - return NULL; - pde_virt[cpu] = v; - } - if ((page = pde_virt[cpu][l1_table_offset_i386(va)]) == 0) /* logical address */ - return NULL; - if (current_is_hvm_compat) - page = p2m_array_compat[page >> PAGE_SHIFT] << PAGE_SHIFT; - if (page != page_phys[cpu]) - { - page_phys[cpu] = page; - if (page_virt[cpu]) - munmap(page_virt[cpu], PAGE_SIZE); - v = mmap( - NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, - map_mtop_offset_compat(page_phys[cpu])); - if (v == MAP_FAILED) - { - IPRINTF("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, l1_table_offset_i386(va)); - page_phys[cpu] = 0; - return NULL; - } - page_virt[cpu] = v; - } - return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK)); -} - -static int -xc_waitdomain_core_compat( - xc_interface *xch, - int domfd, - int *status, - int options) -{ - int nr_vcpus; - int i; - vcpu_guest_context_t *ctxt; - xc_core_header_t header; - - if ( nr_pages_compat == 0 ) - { - if (read(domfd, &header, sizeof(header)) != sizeof(header)) - return -1; - - current_is_hvm_compat = (header.xch_magic == XC_CORE_MAGIC_HVM); - if ( !current_is_hvm_compat && (header.xch_magic != XC_CORE_MAGIC) ) - { - IPRINTF("Magic number missmatch: 0x%08x (file) != " - " 0x%08x (code)\n", header.xch_magic, - XC_CORE_MAGIC); - return -1; - } - - nr_pages_compat = header.xch_nr_pages; - nr_vcpus = header.xch_nr_vcpus; - pages_offset_compat = header.xch_pages_offset; - - if ((ctxt = ptrace_core_get_vcpu_ctxt(xch, nr_vcpus)) == NULL) - { - IPRINTF("Could not allocate vcpu context array\n"); - return -1; - } - - if (read(domfd, ctxt, sizeof(vcpu_guest_context_t)*nr_vcpus) != - sizeof(vcpu_guest_context_t)*nr_vcpus) - return -1; - - for (i = 0; i < nr_vcpus; i++) - cr3[i] = ctxt[i].ctrlreg[3]; - - if ((p2m_array_compat = malloc(nr_pages_compat * sizeof(unsigned long))) == NULL) - { - IPRINTF("Could not allocate p2m_array\n"); - return -1; - } - - if (read(domfd, p2m_array_compat, sizeof(unsigned long)*nr_pages_compat) != - sizeof(unsigned long)*nr_pages_compat) - return -1; - - if ((m2p_array_compat = malloc((1<<20) * sizeof(unsigned long))) == NULL) - { - IPRINTF("Could not allocate m2p array\n"); - return -1; - } - memset(m2p_array_compat, 0, sizeof(unsigned long)* 1 << 20); - - for (i = 0; i < nr_pages_compat; i++) - m2p_array_compat[p2m_array_compat[i]] = i; - } - return 0; -} - - -/* --- new format based on ELF -------------------------------------------- */ -#include "xc_core.h" - -static int -pread_exact(int fd, void* buffer, size_t size, off_t offset) -{ - off_t ret; - unsigned char *buf = buffer; - size_t done = 0; - ret = lseek(fd, offset, SEEK_SET); - if (ret < 0 || ret != offset) - return -1; - - while (done < size) { - ssize_t s = read(fd, buf, size - done); - if (s == -1 && errno == EINTR) - continue; - if (s <= 0) - return -1; - - done += s; - buf += s; - } - return 0; -} - -struct elf_core -{ - int domfd; - Elf64_Ehdr ehdr; - - char* shdr; - - char* shstrtab; - uint64_t shstrtab_size; - - char* note_sec; - uint64_t note_sec_size; -}; - -static int -elf_core_alloc_read_sec_by_index(struct elf_core* ecore, uint16_t index, - char** buf, uint64_t* size); -static int -elf_core_alloc_read_sec_by_name(struct elf_core* ecore, const char* name, - char** buf, uint64_t* size); - -static void -elf_core_free(struct elf_core* ecore) -{ - if (ecore->shdr != NULL) { - free(ecore->shdr); - ecore->shdr = NULL; - } - if (ecore->shstrtab != NULL) { - free(ecore->shstrtab); - ecore->shstrtab = NULL; - } - if (ecore->note_sec != NULL) { - free(ecore->note_sec); - ecore->note_sec = NULL; - } -} - -static int -elf_core_init(struct elf_core* ecore, int domfd) -{ - uint64_t sh_size; - ecore->domfd = domfd; - ecore->shdr = NULL; - ecore->shstrtab = NULL; - ecore->note_sec = NULL; - - if (pread_exact(ecore->domfd, &ecore->ehdr, sizeof(ecore->ehdr), 0) < 0) - goto out; - - /* check elf header */ - if (!IS_ELF(ecore->ehdr) || ecore->ehdr.e_type != ET_CORE) - goto out; - if (ecore->ehdr.e_ident[EI_CLASS] != ELFCLASS64) - goto out; - /* check elf header more: EI_DATA, EI_VERSION, e_machine... */ - - /* read section headers */ - sh_size = ecore->ehdr.e_shentsize * ecore->ehdr.e_shnum; - ecore->shdr = malloc(sh_size); - if (ecore->shdr == NULL) - goto out; - if (pread_exact(ecore->domfd, ecore->shdr, sh_size, - ecore->ehdr.e_shoff) < 0) - goto out; - - /* read shstrtab */ - if (elf_core_alloc_read_sec_by_index(ecore, ecore->ehdr.e_shstrndx, - &ecore->shstrtab, - &ecore->shstrtab_size) < 0) - goto out; - - /* read .note.Xen section */ - if (elf_core_alloc_read_sec_by_name(ecore, XEN_DUMPCORE_SEC_NOTE, - &ecore->note_sec, - &ecore->note_sec_size) < 0) - goto out; - - return 0; -out: - elf_core_free(ecore); - return -1; -} - -static int -elf_core_search_note(struct elf_core* ecore, const char* name, uint32_t type, - void** elfnotep) -{ - const char* note_sec_end = ecore->note_sec + ecore->note_sec_size; - const char* n; - - n = ecore->note_sec; - while (n < note_sec_end) { - const struct elfnote *elfnote = (const struct elfnote *)n; - if (elfnote->namesz == strlen(name) + 1 && - strncmp(elfnote->name, name, elfnote->namesz) == 0 && - elfnote->type == type) { - *elfnotep = (void*)elfnote; - return 0; - } - - n += sizeof(*elfnote) + elfnote->descsz; - } - return -1; -} - -static int -elf_core_alloc_read_sec(struct elf_core* ecore, const Elf64_Shdr* shdr, - char** buf) -{ - int ret; - *buf = malloc(shdr->sh_size); - if (*buf == NULL) - return -1; - ret = pread_exact(ecore->domfd, *buf, shdr->sh_size, shdr->sh_offset); - if (ret < 0) { - free(*buf); - *buf = NULL; - } - return ret; -} - -static Elf64_Shdr* -elf_core_shdr_by_index(struct elf_core* ecore, uint16_t index) -{ - if (index >= ecore->ehdr.e_shnum) - return NULL; - return (Elf64_Shdr*)(ecore->shdr + ecore->ehdr.e_shentsize * index); -} - -static int -elf_core_alloc_read_sec_by_index(struct elf_core* ecore, uint16_t index, - char** buf, uint64_t* size) -{ - Elf64_Shdr* shdr = elf_core_shdr_by_index(ecore, index); - if (shdr == NULL) - return -1; - if (size != NULL) - *size = shdr->sh_size; - return elf_core_alloc_read_sec(ecore, shdr, buf); -} - -static Elf64_Shdr* -elf_core_shdr_by_name(struct elf_core* ecore, const char* name) -{ - const char* s; - for (s = ecore->shdr; - s < ecore->shdr + ecore->ehdr.e_shentsize * ecore->ehdr.e_shnum; - s += ecore->ehdr.e_shentsize) { - Elf64_Shdr* shdr = (Elf64_Shdr*)s; - - if (strncmp(ecore->shstrtab + shdr->sh_name, name, strlen(name)) == 0) - return shdr; - } - - return NULL; -} - -static int -elf_core_read_sec_by_name(struct elf_core* ecore, const char* name, char* buf) -{ - Elf64_Shdr* shdr = elf_core_shdr_by_name(ecore, name); - return pread_exact(ecore->domfd, buf, shdr->sh_size, shdr->sh_offset); - -} - -static int -elf_core_alloc_read_sec_by_name(struct elf_core* ecore, const char* name, - char** buf, uint64_t* size) -{ - Elf64_Shdr* shdr = elf_core_shdr_by_name(ecore, name); - if (shdr == NULL) - return -1; - if (size != NULL) - *size = shdr->sh_size; - return elf_core_alloc_read_sec(ecore, shdr, buf); -} - -/* XXX application state */ -static int current_is_auto_translated_physmap = 0; -static struct xen_dumpcore_p2m* p2m_array = NULL; /* for non auto translated physmap mode */ -static uint64_t p2m_array_size = 0; -static uint64_t* pfn_array = NULL; /* for auto translated physmap mode */ -static uint64_t pfn_array_size = 0; -static long nr_pages = 0; -static uint64_t pages_offset; - -static const struct xen_dumpcore_elfnote_format_version_desc -known_format_version[] = -{ - {XEN_DUMPCORE_FORMAT_VERSION((uint64_t)0, (uint64_t)1)}, -}; -#define KNOWN_FORMAT_VERSION_NR \ - (sizeof(known_format_version)/sizeof(known_format_version[0])) - -static unsigned long -map_gmfn_to_offset_elf(unsigned long gmfn) -{ - /* - * linear search - */ - unsigned long i; - if (current_is_auto_translated_physmap) { - if (pfn_array == NULL) - return 0; - for (i = 0; i < pfn_array_size; i++) { - if (pfn_array[i] == gmfn) { - return pages_offset + (i << PAGE_SHIFT); - } - } - } else { - if (p2m_array == NULL) - return 0; - for (i = 0; i < p2m_array_size; i++) { - if (p2m_array[i].gmfn == gmfn) { - return pages_offset + (i << PAGE_SHIFT); - } - } - } - return 0; -} - -static void * -map_domain_va_core_elf(xc_interface *xch, - unsigned long domfd, int cpu, void *guest_va) -{ - unsigned long pde, page; - unsigned long va = (unsigned long)guest_va; - unsigned long offset; - void *v; - - if (cr3[cpu] != cr3_phys[cpu]) - { - if (cr3_virt[cpu]) - { - munmap(cr3_virt[cpu], PAGE_SIZE); - cr3_virt[cpu] = NULL; - cr3_phys[cpu] = 0; - } - offset = map_gmfn_to_offset_elf(xen_cr3_to_pfn(cr3[cpu])); - if (offset == 0) - return NULL; - v = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, offset); - if (v == MAP_FAILED) - { - PERROR("mmap failed"); - return NULL; - } - cr3_phys[cpu] = cr3[cpu]; - cr3_virt[cpu] = v; - } - if ((pde = cr3_virt[cpu][l2_table_offset_i386(va)]) == 0) /* logical address */ - return NULL; - if (pde != pde_phys[cpu]) - { - if (pde_virt[cpu]) - { - munmap(pde_virt[cpu], PAGE_SIZE); - pde_virt[cpu] = NULL; - pde_phys[cpu] = 0; - } - offset = map_gmfn_to_offset_elf(pde >> PAGE_SHIFT); - if (offset == 0) - return NULL; - v = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, offset); - if (v == MAP_FAILED) - return NULL; - pde_phys[cpu] = pde; - pde_virt[cpu] = v; - } - if ((page = pde_virt[cpu][l1_table_offset_i386(va)]) == 0) /* logical address */ - return NULL; - if (page != page_phys[cpu]) - { - if (page_virt[cpu]) - { - munmap(page_virt[cpu], PAGE_SIZE); - page_virt[cpu] = NULL; - page_phys[cpu] = 0; - } - offset = map_gmfn_to_offset_elf(page >> PAGE_SHIFT); - if (offset == 0) - return NULL; - v = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, offset); - if (v == MAP_FAILED) - { - IPRINTF("cr3 %lx pde %lx page %lx pti %lx\n", - cr3[cpu], pde, page, l1_table_offset_i386(va)); - return NULL; - } - page_phys[cpu] = page; - page_virt[cpu] = v; - } - return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK)); -} - -static int -xc_waitdomain_core_elf( - xc_interface *xch, - int domfd, - int *status, - int options) -{ - int i; - vcpu_guest_context_t *ctxt; - struct elf_core ecore; - - struct xen_dumpcore_elfnote_none *none; - struct xen_dumpcore_elfnote_header *header; - struct xen_dumpcore_elfnote_xen_version *xen_version; - struct xen_dumpcore_elfnote_format_version *format_version; - - Elf64_Shdr* table_shdr; - Elf64_Shdr* pages_shdr; - - if (elf_core_init(&ecore, domfd) < 0) - goto out; - - /* .note.Xen: none */ - if (elf_core_search_note(&ecore, XEN_DUMPCORE_ELFNOTE_NAME, - XEN_ELFNOTE_DUMPCORE_NONE, (void**)&none) < 0) - goto out; - - /* .note.Xen: header */ - if (elf_core_search_note(&ecore, XEN_DUMPCORE_ELFNOTE_NAME, - XEN_ELFNOTE_DUMPCORE_HEADER, (void**)&header) < 0) - goto out; - if ((header->header.xch_magic != XC_CORE_MAGIC && - header->header.xch_magic != XC_CORE_MAGIC_HVM) || - header->header.xch_nr_vcpus == 0 || - header->header.xch_nr_pages == 0 || - header->header.xch_page_size != PAGE_SIZE) - goto out; - current_is_auto_translated_physmap = - (header->header.xch_magic == XC_CORE_MAGIC_HVM); - nr_pages = header->header.xch_nr_pages; - - /* .note.Xen: xen_version */ - if (elf_core_search_note(&ecore, XEN_DUMPCORE_ELFNOTE_NAME, - XEN_ELFNOTE_DUMPCORE_XEN_VERSION, - (void**)&xen_version) < 0) - goto out; - /* shifted case covers 32 bit FV guest core file created on 64 bit Dom0 */ - if (xen_version->xen_version.pagesize != PAGE_SIZE && - (xen_version->xen_version.pagesize >> 32) != PAGE_SIZE) - goto out; - - /* .note.Xen: format_version */ - if (elf_core_search_note(&ecore, XEN_DUMPCORE_ELFNOTE_NAME, - XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION, - (void**)&format_version) < 0) - goto out; - for (i = 0; i < KNOWN_FORMAT_VERSION_NR; i++) { - if (format_version->format_version.version == - known_format_version[i].version) - break; - } - if (i == KNOWN_FORMAT_VERSION_NR) { - /* complain if unknown format */ - IPRINTF("warning:unknown format version. %"PRIx64"\n", - format_version->format_version.version); - } - - if ((ctxt = ptrace_core_get_vcpu_ctxt(xch, header->header.xch_nr_vcpus)) == NULL) - goto out; - - /* .xen_prstatus: read vcpu_guest_context_t*/ - if (elf_core_read_sec_by_name(&ecore, XEN_DUMPCORE_SEC_PRSTATUS, - (char*)ctxt) < 0) - goto out; - for (i = 0; i < header->header.xch_nr_vcpus; i++) - cr3[i] = ctxt[i].ctrlreg[3]; - - /* read .xen_p2m or .xen_pfn */ - if (current_is_auto_translated_physmap) { - table_shdr = elf_core_shdr_by_name(&ecore, XEN_DUMPCORE_SEC_PFN); - if (table_shdr == NULL) - goto out; - pfn_array_size = table_shdr->sh_size / table_shdr->sh_entsize; - if (pfn_array != NULL) - free(pfn_array); - if (elf_core_alloc_read_sec(&ecore, table_shdr, - (char**)&pfn_array) < 0) - goto out; - if (table_shdr->sh_entsize != sizeof(pfn_array[0])) - goto out; - } else { - table_shdr = elf_core_shdr_by_name(&ecore, XEN_DUMPCORE_SEC_P2M); - if (table_shdr == NULL) - goto out; - p2m_array_size = table_shdr->sh_size / table_shdr->sh_entsize; - if (p2m_array != NULL) - free(p2m_array); - if (elf_core_alloc_read_sec(&ecore, table_shdr, - (char**)&p2m_array) < 0) - goto out; - if (table_shdr->sh_entsize != sizeof(p2m_array[0])) - goto out; - } - if (table_shdr->sh_size / table_shdr->sh_entsize != nr_pages) - goto out; - - /* pages_offset and check the file size */ - pages_shdr = elf_core_shdr_by_name(&ecore, XEN_DUMPCORE_SEC_PAGES); - if (pages_shdr == NULL) - goto out; - pages_offset = pages_shdr->sh_offset; - if ((pages_shdr->sh_size / pages_shdr->sh_entsize) != nr_pages || - pages_shdr->sh_entsize != PAGE_SIZE || - (pages_shdr->sh_addralign % PAGE_SIZE) != 0 || - (pages_offset % PAGE_SIZE) != 0) - goto out; - - elf_core_free(&ecore); - return 0; - -out: - elf_core_free(&ecore); - return -1; -} - -/* --- interface ----------------------------------------------------------- */ - -typedef int (*xc_waitdomain_core_t)(xc_interface *xch, - int domfd, - int *status, - int options); -typedef void *(*map_domain_va_core_t)(xc_interface *xch, - unsigned long domfd, - int cpu, - void *guest_va); -struct xc_core_format_type { - xc_waitdomain_core_t waitdomain_core; - map_domain_va_core_t map_domain_va_core; -}; - -static const struct xc_core_format_type format_type[] = { - {xc_waitdomain_core_elf, map_domain_va_core_elf}, - {xc_waitdomain_core_compat, map_domain_va_core_compat}, -}; -#define NR_FORMAT_TYPE (sizeof(format_type)/sizeof(format_type[0])) - -/* XXX application state */ -static const struct xc_core_format_type* current_format_type = NULL; - -void * -map_domain_va_core(xc_interface *xch, - unsigned long domfd, int cpu, void *guest_va) -{ - if (current_format_type == NULL) - return NULL; - return (current_format_type->map_domain_va_core)(xch, domfd, cpu, guest_va); -} - -int -xc_waitdomain_core(xc_interface *xch, int domfd, int *status, int options) -{ - int ret; - int i; - - for (i = 0; i < NR_FORMAT_TYPE; i++) { - ret = (format_type[i].waitdomain_core)(xch, domfd, status, - options); - if (ret == 0) { - current_format_type = &format_type[i]; - break; - } - } - return ret; -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff -r 81503caeb439 -r 5922a25d3039 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Sun Aug 22 09:53:51 2010 +0100 +++ b/tools/libxc/xenctrl.h Mon Aug 23 09:02:34 2010 +0100 @@ -149,32 +149,6 @@ typedef struct xc_core_header { #define XC_CORE_MAGIC 0xF00FEBED #define XC_CORE_MAGIC_HVM 0xF00FEBEE - -#if 0 /*def __linux__*/ - -#include <sys/ptrace.h> -#include <thread_db.h> - -typedef void (*thr_ev_handler_t)(long); - -void xc_register_event_handler( - thr_ev_handler_t h, - td_event_e e); - -long xc_ptrace( - xc_interface *xch, - enum __ptrace_request request, - uint32_t domid, - long addr, - long data); - -int xc_waitdomain( - xc_interface *xch, - int domain, - int *status, - int options); - -#endif /* __linux__ */ /* * DOMAIN MANAGEMENT FUNCTIONS _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |