From: Don Slutz <dslutz@verizon.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
George Dunlap <george.dunlap@eu.citrix.com>,
Don Slutz <Don@CloudSwitch.com>,
Ian Jackson <ian.jackson@eu.citrix.com>,
Don Slutz <dslutz@verizon.com>,
xen-devel@lists.xen.org
Subject: Re: [PATCH] Add xentrace/xen_crash.
Date: Tue, 15 Oct 2013 10:53:28 -0400 [thread overview]
Message-ID: <525D56E8.8050204@terremark.com> (raw)
In-Reply-To: <525C07DD.7000206@citrix.com>
On 10/14/13 11:03, Andrew Cooper wrote:
> On 14/10/13 15:07, Don Slutz wrote:
>> From: Don Slutz <Don@CloudSwitch.com>
>>
>> This allows crash to connect to a domU. Usage:
>>
>> usage: xen_crash <domid> [<optional port>]
>>
>> xen_crash 1&
>> crash localhost:5001 /usr/lib/debug/lib/modules/3.8.11-100.fc17.x86_64/vmlinux
>>
>> The domU will be paused while crash is connected. Currently the code exits when crash disconnects.
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
> This looks good in principle.
>
> However, I am not sure tools/xentrace/ is an appropriate place for it,
> as it is unrelated to xentrace.
I was not sure either. Parts are based on xenctx which is here.
> Also, the name "xen_crash" is a bit too generic, and implies its purpose
> is to crash a guest, rather than to attach `crash` to a guest.
>
> What about xen-crashd, as it is a daemon?
That would be fine with me.
>
> ~Andrew
-Don Slutz
>> ---
>> .gitignore | 1 +
>> tools/xentrace/Makefile | 5 +-
>> tools/xentrace/xen_crash.c | 697 ++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 702 insertions(+), 1 deletions(-)
>> create mode 100644 tools/xentrace/xen_crash.c
>>
>> diff --git a/.gitignore b/.gitignore
>> index 3253675..51226f5 100644
>> --- a/.gitignore
>> +++ b/.gitignore
>> @@ -278,6 +278,7 @@ tools/xenstore/xs_watch_stress
>> tools/xentrace/xentrace_setsize
>> tools/xentrace/tbctl
>> tools/xentrace/xenctx
>> +tools/xentrace/xen_crash
>> tools/xentrace/xentrace
>> tools/xm-test/ramdisk/buildroot
>> tools/xm-test/aclocal.m4
>> diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile
>> index 63b09c0..a2313c6 100644
>> --- a/tools/xentrace/Makefile
>> +++ b/tools/xentrace/Makefile
>> @@ -7,7 +7,7 @@ CFLAGS += $(CFLAGS_libxenctrl)
>> LDLIBS += $(LDLIBS_libxenctrl)
>>
>> BIN = xentrace xentrace_setsize
>> -LIBBIN = xenctx
>> +LIBBIN = xenctx xen_crash
>> SCRIPTS = xentrace_format
>> MAN1 = $(wildcard *.1)
>> MAN8 = $(wildcard *.8)
>> @@ -40,6 +40,9 @@ xentrace: xentrace.o
>> xenctx: xenctx.o
>> $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) $(APPEND_LDFLAGS)
>>
>> +xen_crash: xen_crash.o
>> + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) $(APPEND_LDFLAGS)
>> +
>> xentrace_setsize: setsize.o
>> $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) $(APPEND_LDFLAGS)
>>
>> diff --git a/tools/xentrace/xen_crash.c b/tools/xentrace/xen_crash.c
>> new file mode 100644
>> index 0000000..6a4bb34
>> --- /dev/null
>> +++ b/tools/xentrace/xen_crash.c
>> @@ -0,0 +1,697 @@
>> +/******************************************************************************
>> + * tools/xentrace/xen_crash.c
>> + *
>> + * Connect crash to DOMu.
>> + *
>> + * Copyright (C) 2012 by Cloud Switch, Inc.
>> + *
>> + */
>> +
>> +#include <ctype.h>
>> +#include <time.h>
>> +#include <stdlib.h>
>> +#include <sys/mman.h>
>> +#include <stdio.h>
>> +#include <sys/types.h>
>> +#include <sys/socket.h>
>> +#include <sys/ioctl.h>
>> +#include <sys/time.h>
>> +#include <sys/stat.h>
>> +#include <netinet/in.h>
>> +#include <netdb.h>
>> +#include <fcntl.h>
>> +#include <unistd.h>
>> +#include <errno.h>
>> +#include <signal.h>
>> +#include <string.h>
>> +#include <inttypes.h>
>> +#include <getopt.h>
>> +
>> +#include "xenctrl.h"
>> +#include <xen/foreign/x86_32.h>
>> +#include <xen/foreign/x86_64.h>
>> +#include <xen/hvm/save.h>
>> +
>> +xc_interface *xc_handle = 0;
>> +int domid = 0;
>> +int debug = 0;
>> +
>> +typedef unsigned long long guest_word_t;
>> +#define FMT_32B_WORD "%08llx"
>> +#define FMT_64B_WORD "%016llx"
>> +
>> +/* Word-length of the guest's own data structures */
>> +int guest_word_size = sizeof (unsigned long);
>> +/* Word-length of the context record we get from xen */
>> +int ctxt_word_size = sizeof (unsigned long);
>> +int guest_protected_mode = 1;
>> +
>> +#define MACHINE_TYPE "X86_64"
>> +
>> +#define STRNEQ(A, B) (B && \
>> + (strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0))
>> +#define FAILMSG "FAIL "
>> +#define DONEMSG "DONE "
>> +#define DATAMSG "DATA "
>> +
>> +#define DATA_HDRSIZE 13 /* strlen("XXXX ") + strlen("0131072") + NULL */
>> +
>> +#define BUFSIZE 127
>> +#define READBUFSIZE DATA_HDRSIZE + XC_PAGE_SIZE
>> +
>> +#define MAX_REMOTE_FDS 10
>> +
>> +void
>> +print_now(void)
>> +{
>> + struct timeval tp;
>> + struct timezone tzp;
>> + char *timeout;
>> + int imil;
>> +
>> + gettimeofday(&tp, &tzp);
>> + timeout = ctime(&tp.tv_sec);
>> + imil = tp.tv_usec / 1000;
>> + timeout += 4; /* Skip day of week */
>> + *(timeout + 3) = 0; /* Trim at space after month */
>> + *(timeout + 6) = 0; /* Trim at space after day */
>> + *(timeout + 15) = 0; /* Trim at seconds. */
>> + *(timeout + 20) = 0; /* Trim after year. */
>> + printf("%s %s %s %s.%.3d ", timeout + 4, timeout, timeout + 18,
>> + timeout + 7, imil);
>> +}
>> +
>> +int
>> +RTTcpWrite(int Sock, const void *pvBuffer, size_t cbBuffer)
>> +{
>> + if (debug & 4) {
>> + print_now();
>> + printf("rtn: %s\n", (char*)pvBuffer);
>> + }
>> + do
>> + {
>> + size_t cbNow = cbBuffer;
>> + ssize_t cbWritten = send(Sock, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);
>> +
>> + if (cbWritten < 0)
>> + return 1;
>> + cbBuffer -= cbWritten;
>> + pvBuffer = (char *)pvBuffer + cbWritten;
>> + } while (cbBuffer);
>> +
>> + return 0;
>> +}
>> +
>> +
>> +static void *
>> +map_page(int vcpu, guest_word_t phys)
>> +{
>> + static unsigned long previous_mfn = 0;
>> + static void *mapped = NULL;
>> +
>> + unsigned long mfn = phys >> XC_PAGE_SHIFT;
>> + unsigned long offset = phys & ~XC_PAGE_MASK;
>> +
>> + if (mapped && mfn == previous_mfn)
>> + goto out;
>> +
>> + if (mapped)
>> + munmap(mapped, XC_PAGE_SIZE);
>> +
>> + previous_mfn = mfn;
>> +
>> + mapped = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE, PROT_READ, mfn);
>> +
>> + if (mapped == NULL) {
>> + if (debug & 2) {
>> + print_now();
>> + printf("failed to map page for %08llx.\n", phys);
>> + }
>> + return NULL;
>> + }
>> +
>> + out:
>> + return (void *)(mapped + offset);
>> +}
>> +
>> +static int
>> +copy_phys(int vcpu, char * pvDst, size_t cb, guest_word_t phys)
>> +{
>> + void * localAddr;
>> + size_t cbPage = XC_PAGE_SIZE - (phys & ~XC_PAGE_MASK);
>> +
>> + /* optimize for the case where access is completely within the first page. */
>> + localAddr = map_page(vcpu, phys);
>> + if (!localAddr) {
>> + return 2;
>> + }
>> + if (cb <= cbPage) {
>> + memcpy(pvDst, localAddr, cb);
>> + return 0;
>> + }
>> + memcpy(pvDst, localAddr, cbPage);
>> + pvDst += cbPage;
>> + phys += cbPage;
>> + cb -= cbPage;
>> +
>> + /* Max transfer is XC_PAGE_SIZE... */
>> + if (cb > XC_PAGE_SIZE)
>> + return 1;
>> + localAddr = map_page(vcpu, phys);
>> + if (!localAddr) {
>> + return 3;
>> + }
>> + memcpy(pvDst, localAddr, cb);
>> + return 0;
>> +}
>> +
>> +static guest_word_t
>> +convert_to_phys(int vcpu, guest_word_t virt)
>> +{
>> + unsigned long mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, virt);
>> + unsigned long offset = virt & ~XC_PAGE_MASK;
>> +
>> + return (mfn << XC_PAGE_SHIFT) + offset;
>> +}
>> +
>> +static int
>> +copy_virt(int vcpu, char * pvDst, size_t cb, guest_word_t virt)
>> +{
>> + void * localAddr;
>> + unsigned long mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, virt);
>> + unsigned long offset = virt & ~XC_PAGE_MASK;
>> + guest_word_t phys = (mfn << XC_PAGE_SHIFT) + offset;
>> + size_t cbPage = XC_PAGE_SIZE - offset;
>> +
>> + /* optimize for the case where access is completely within the first page. */
>> +
>> + localAddr = map_page(vcpu, phys);
>> + if (!localAddr) {
>> + return 2;
>> + }
>> + if (cb <= cbPage) {
>> + memcpy(pvDst, localAddr, cb);
>> + return 0;
>> + }
>> + memcpy(pvDst, localAddr, cbPage);
>> + pvDst += cbPage;
>> + phys += cbPage;
>> + cb -= cbPage;
>> +
>> + /* Max transfer is XC_PAGE_SIZE... */
>> + if (cb > XC_PAGE_SIZE)
>> + return 1;
>> + localAddr = map_page(vcpu, phys);
>> + if (!localAddr) {
>> + return 3;
>> + }
>> + memcpy(pvDst, localAddr, cb);
>> + return 0;
>> +}
>> +
>> +int main(int argc, char **argv)
>> +{
>> + int port=5001;
>> + int sock;
>> + unsigned int length;
>> + struct sockaddr_in server;
>> + int msgsock;
>> + int nfds;
>> + int reuseaddr;
>> + int count;
>> + int pass;
>> + int i;
>> + char recvbuf[BUFSIZE + 1];
>> + char sendbuf[READBUFSIZE + 1];
>> + int fds[MAX_REMOTE_FDS];
>> + size_t cbRead = 0;
>> +
>> + int ret;
>> + int vcpu;
>> + vcpu_guest_context_any_t ctx;
>> + xc_dominfo_t dominfo;
>> + struct hvm_hw_cpu cpuctx;
>> +
>> + if (argc < 2 || argc > 4) {
>> + printf("usage: xen_crash <domid> [<optional port>]\n");
>> + exit(-1);
>> + }
>> +
>> + domid = atoi(argv[1]);
>> + if (domid==0) {
>> + fprintf(stderr, "cannot trace dom0\n");
>> + exit(-1);
>> + }
>> +
>> + if (argc > 2)
>> + port = atoi(argv[2]);
>> + if (argc > 3)
>> + debug = atoi(argv[3]);
>> +
>> + signal(SIGPIPE, SIG_IGN);
>> +
>> + sock = socket(AF_INET, SOCK_STREAM, 0);
>> + if (sock < 0) {
>> + perror("socket()");
>> + exit(1);
>> + }
>> + reuseaddr = 1;
>> + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr,
>> + sizeof reuseaddr) < 0) {
>> + perror("setsockopt()");
>> + exit(2);
>> + }
>> + server.sin_family = AF_INET;
>> + server.sin_addr.s_addr = INADDR_ANY;
>> + server.sin_port = htons(port);
>> + count = -1;
>> + errno = EADDRINUSE;
>> + for (pass=0; (errno == EADDRINUSE) && (count < 0); pass++) {
>> + if ((count = bind(sock, (struct sockaddr *) & server, sizeof server)) <
>> + 0) {
>> + if (errno != EADDRINUSE) {
>> + /* printf("Errno is %d\n", errno); */
>> + perror("bind()");
>> + exit(3);
>> + }
>> + sleep(1); /* Waiting for kernel... */
>> + }
>> + }
>> + length = sizeof server;
>> + if (getsockname(sock, (struct sockaddr *) & server, &length) < 0) {
>> + perror("getsockname()");
>> + exit(4);
>> + }
>> + print_now();
>> + if (pass == 1)
>> + printf("Socket ready on port %d after 1 bind call\n", port);
>> + else
>> + printf("Socket ready on port %d after %d bind calls\n", port, pass);
>> + listen(sock, 1);
>> + msgsock = accept(sock, NULL, NULL);
>> + if (msgsock == -1)
>> + perror("accept()");
>> + else {
>> + print_now();
>> + printf("Accepted a connection.\n");
>> + close(sock); /* All done for now */
>> + errno = 0; /* Just in case */
>> + nfds = msgsock + 1;
>> + }
>> +
>> + xc_handle = xc_interface_open(0,0,0); /* for accessing control interface */
>> +
>> + ret = xc_domain_getinfo(xc_handle, domid, 1, &dominfo);
>> + if (ret < 0) {
>> + perror("xc_domain_getinfo");
>> + exit(-1);
>> + }
>> +
>> + ret = xc_domain_pause(xc_handle, domid);
>> + if (ret < 0) {
>> + perror("xc_domain_pause");
>> + exit(-1);
>> + }
>> +
>> + vcpu = 0;
>> + ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
>> + if (ret < 0) {
>> + if (!dominfo.paused)
>> + xc_domain_unpause(xc_handle, domid);
>> + perror("xc_vcpu_getcontext");
>> + exit(-1);
>> + }
>> +
>> + if (dominfo.hvm) {
>> + xen_capabilities_info_t xen_caps = "";
>> + if (xc_domain_hvm_getcontext_partial(
>> + xc_handle, domid, HVM_SAVE_CODE(CPU),
>> + vcpu, &cpuctx, sizeof cpuctx) != 0) {
>> + perror("xc_domain_hvm_getcontext_partial");
>> + exit(-1);
>> + }
>> + guest_word_size = (cpuctx.msr_efer & 0x400) ? 8 : 4;
>> + guest_protected_mode = (cpuctx.cr0 & 0x1);
>> + /* HVM guest context records are always host-sized */
>> + if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
>> + perror("xc_version");
>> + exit(-1);
>> + }
>> + ctxt_word_size = (strstr(xen_caps, "xen-3.0-x86_64")) ? 8 : 4;
>> + } else {
>> + struct xen_domctl domctl;
>> + memset(&domctl, 0, sizeof domctl);
>> + domctl.domain = domid;
>> + domctl.cmd = XEN_DOMCTL_get_address_size;
>> + if (xc_domctl(xc_handle, &domctl) == 0)
>> + ctxt_word_size = guest_word_size = domctl.u.address_size.size / 8;
>> + }
>> +
>> + for (i = 0; i < MAX_REMOTE_FDS; i++)
>> + fds[i] = -1;
>> +
>> + do {
>> + cbRead = recv(msgsock, recvbuf, BUFSIZE, MSG_NOSIGNAL);
>> + if (cbRead <= 0) {
>> + close(msgsock);
>> + msgsock = -1;
>> + break;
>> + }
>> + recvbuf[cbRead] = 0;
>> +
>> + if (debug & 1) {
>> + print_now();
>> + printf("req: %s\n", recvbuf);
>> + }
>> +
>> + if (STRNEQ(recvbuf, "READ_LIVE"))
>> + {
>> + char *p1, *p2, *p3, *p4;
>> + int rc2 = 0;
>> + guest_word_t addr;
>> + int fid;
>> + int len;
>> +
>> + p1 = strtok(recvbuf, " "); /* READ_LIVE */
>> + p1 = strtok(NULL, " "); /* fid */
>> + p2 = strtok(NULL, " "); /* paddress or vaddress */
>> + p3 = strtok(NULL, " "); /* length */
>> + p4 = strtok(NULL, " "); /* vaddress or vcpu */
>> +
>> + fid = atoi(p1);
>> + addr = strtoull(p2, NULL, 16);
>> + len = atoi(p3);
>> + if (len < 0 || len > XC_PAGE_SIZE)
>> + {
>> + print_now();
>> + printf("bad len=%d page_size=%ld;%s %s %s %s %s\n",
>> + len, XC_PAGE_SIZE, recvbuf, p1, p2, p3, p4);
>> + len = 0;
>> + rc2 = 4;
>> + }
>> +
>> + if (len)
>> + {
>> + if (p4 && (fds[fid] == 3)) {
>> + int myCpu = atoi(p4);
>> + guest_word_t pAddr = convert_to_phys(myCpu, addr);
>> +
>> + if (debug & 2) {
>> + print_now();
>> + printf("copy_virt(%d,,%d, 0x%llx)[%s %s %s %s] pAddr=0x%lx\n",
>> + myCpu, len, addr, p1, p2, p3, p4, (long)pAddr);
>> + }
>> + rc2 = copy_virt(myCpu, &sendbuf[DATA_HDRSIZE], len, addr);
>> + } else {
>> + if (debug & 2) {
>> + print_now();
>> + printf("copy_phys(%d,,%d, 0x%llx)[%s %s %s]\n",
>> + vcpu, len, addr, p1, p2, p3);
>> + }
>> + rc2 = copy_phys(vcpu, &sendbuf[DATA_HDRSIZE], len, addr);
>> + }
>> + if (rc2) {
>> + if (debug & 2) {
>> + print_now();
>> + printf("Failed rc2=%d\n", rc2);
>> + }
>> + len = 0;
>> + }
>> + }
>> +
>> + if (!len) {
>> + snprintf(sendbuf, sizeof(sendbuf), "%s%07ld", FAILMSG, (ulong)rc2);
>> + } else {
>> + snprintf(sendbuf, sizeof(sendbuf), "%s%07ld", DONEMSG, (ulong)len);
>> + }
>> + if (RTTcpWrite(msgsock, sendbuf, len + DATA_HDRSIZE))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "FETCH_LIVE_IP_SP_BP "))
>> + {
>> + char *p1, *p2;
>> + int cpu;
>> + long g2ip = 0;
>> + short g2cs = 0;
>> + short g2ss = 0;
>> + long g2sp = 0;
>> + long g2bp = 0;
>> +
>> + p1 = strtok(recvbuf, " "); /* FETCH_LIVE_IP_SP_BP */
>> + p2 = strtok(NULL, " "); /* cpu */
>> +
>> + cpu = atoi(p2);
>> + if (cpu != vcpu) {
>> + vcpu = cpu;
>> + ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
>> + if (ret < 0) {
>> + if (!dominfo.paused)
>> + xc_domain_unpause(xc_handle, domid);
>> + perror("xc_vcpu_getcontext");
>> + exit(-1);
>> + }
>> + if (dominfo.hvm) {
>> + if (xc_domain_hvm_getcontext_partial(
>> + xc_handle, domid, HVM_SAVE_CODE(CPU),
>> + vcpu, &cpuctx, sizeof cpuctx) != 0) {
>> + perror("xc_domain_hvm_getcontext_partial");
>> + exit(-1);
>> + }
>> + }
>> + }
>> +
>> + if (ctxt_word_size == 4) {
>> + struct cpu_user_regs_x86_32 * regs = &(ctx.x32.user_regs);
>> +
>> + g2ip = regs->eip;
>> + g2sp = regs->esp;
>> + g2bp = regs->ebp;
>> + g2cs = regs->cs;
>> + g2ss = regs->ss;
>> + } else {
>> + struct cpu_user_regs_x86_64 * regs = &(ctx.x64.user_regs);
>> +
>> + if (dominfo.hvm) {
>> + g2ip = cpuctx.rip;
>> + g2sp = cpuctx.rsp;
>> + g2bp = cpuctx.rbp;
>> + g2cs = cpuctx.cs_sel;
>> + g2ss = cpuctx.ss_sel;
>> + if (debug & 0x100) {
>> + if (g2ip != regs->rip) {
>> + printf("g2ip(%lx) != rip(%lx)\n", g2ip, regs->rip);
>> + }
>> + if (g2sp != regs->rsp) {
>> + printf("g2sp(%lx) != rsp(%lx)\n", g2sp, regs->rsp);
>> + }
>> + if (g2bp != regs->rbp) {
>> + printf("g2bp(%lx) != rbp(%lx)\n", g2bp, regs->rbp);
>> + }
>> + if (g2cs != regs->cs) {
>> + printf("g2cs(%x) != cs(%x)\n", g2cs, regs->cs);
>> + }
>> + if (g2ss != regs->ss) {
>> + printf("g2ss(%x) != ss(%x)\n", g2ss, regs->ss);
>> + }
>> + }
>> + } else {
>> + g2ip = regs->rip;
>> + g2sp = regs->rsp;
>> + g2bp = regs->rbp;
>> + g2cs = regs->cs;
>> + g2ss = regs->ss;
>> + }
>> + }
>> +
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %d %04x:%lx %04x:%lx %lx",
>> + p1, cpu, g2cs, g2ip, g2ss, g2sp, g2bp);
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "FETCH_LIVE_CR3 "))
>> + {
>> + char *p1, *p2;
>> + int cpu;
>> + long g2cr3 = 0;
>> +
>> + p1 = strtok(recvbuf, " "); /* FETCH_LIVE_CR3 */
>> + p2 = strtok(NULL, " "); /* cpu */
>> +
>> + cpu = atoi(p2);
>> + if (cpu != vcpu) {
>> + vcpu = cpu;
>> + ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
>> + if (ret < 0) {
>> + if (!dominfo.paused)
>> + xc_domain_unpause(xc_handle, domid);
>> + perror("xc_vcpu_getcontext");
>> + exit(-1);
>> + }
>> + if (dominfo.hvm) {
>> + if (xc_domain_hvm_getcontext_partial(
>> + xc_handle, domid, HVM_SAVE_CODE(CPU),
>> + vcpu, &cpuctx, sizeof cpuctx) != 0) {
>> + perror("xc_domain_hvm_getcontext_partial");
>> + exit(-1);
>> + }
>> + }
>> + }
>> +
>> + if (ctxt_word_size == 4) {
>> + g2cr3 = ctx.x32.ctrlreg[3];
>> + } else {
>> + if (dominfo.hvm) {
>> + g2cr3 = cpuctx.cr3;
>> + if (debug & 0x100) {
>> + if (g2cr3 != ctx.x64.ctrlreg[3]) {
>> + printf("g2cr3(%lx) != cr3(%lx)\n", g2cr3, ctx.x64.ctrlreg[3]);
>> + }
>> + }
>> + } else {
>> + g2cr3 = ctx.x64.ctrlreg[3];
>> + }
>> + }
>> +
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %d %lx",
>> + p1, cpu, g2cr3);
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "MACHINE_PID"))
>> + {
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %s %d",
>> + recvbuf, MACHINE_TYPE, 0);
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "VTOP"))
>> + {
>> + char *p1, *p2, *p3;
>> + int cpu;
>> + guest_word_t vAddr, pAddr;
>> +
>> + p1 = strtok(recvbuf, " "); /* VTOP */
>> + p2 = strtok(NULL, " "); /* cpu */
>> + p3 = strtok(NULL, " "); /* vaddress */
>> +
>> + cpu = atoi(p2);
>> + vAddr = strtoull(p3, NULL, 16);
>> +
>> + pAddr = convert_to_phys(cpu, vAddr);
>> +
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %d %lx %lx",
>> + p1, cpu, (long)vAddr, (long)pAddr);
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "OPEN "))
>> + {
>> + char *p1;
>> + char *file;
>> +
>> + p1 = strtok(recvbuf, " "); /* OPEN */
>> + file = strtok(NULL, " "); /* filename */
>> +
>> + for (i = 0; i < MAX_REMOTE_FDS; i++) {
>> + if (fds[i] == -1)
>> + break;
>> + }
>> +
>> + if (i < MAX_REMOTE_FDS) {
>> + if (STRNEQ(file, "/dev/mem"))
>> + {
>> + fds[i] = 1;
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %s %d O_RDONLY %lld", p1, file, i, 1024LL * 1024LL * 1024LL * 1024LL);
>> + }
>> + else if (STRNEQ(file, "/dev/kmem"))
>> + {
>> + fds[i] = 2;
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %s %d O_RDONLY %lld", p1, file, i, 1024LL * 1024LL * 1024LL * 1024LL);
>> + }
>> + else if (STRNEQ(file, "/dev/vmem"))
>> + {
>> + fds[i] = 3;
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %s %d O_RDONLY %lld", p1, file, i, 1024LL * 1024LL * 1024LL * 1024LL);
>> + }
>> + else
>> + {
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %s <FAIL>", p1, file);
>> + }
>> + }
>> + else
>> + {
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %s <FAIL>", p1, file);
>> + }
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "CLOSE "))
>> + {
>> + char *p1, *p2;
>> +
>> + p1 = strtok(recvbuf, " "); /* SIZE */
>> + p2 = strtok(NULL, " "); /* filename id */
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %s <FAIL>", p1, p2);
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "PROC_VERSION"))
>> + {
>> + /*
>> + * Perform the detection.
>> + */
>> + snprintf(sendbuf, sizeof(sendbuf), "<FAIL>");
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "PAGESIZE LIVE"))
>> + {
>> + snprintf(sendbuf, sizeof(sendbuf), "%s %ld XEN %d",
>> + recvbuf, XC_PAGE_SIZE, dominfo.max_vcpu_id + 1);
>> + if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + else if (STRNEQ(recvbuf, "EXIT"))
>> + {
>> + snprintf(sendbuf, sizeof(sendbuf), "%s OK", recvbuf);
>> + RTTcpWrite(msgsock, sendbuf, strlen(sendbuf));
>> + break;
>> + }
>> + else
>> + {
>> + print_now();
>> + printf("unknown: %s\n", recvbuf);
>> + snprintf(sendbuf, sizeof(sendbuf), "%s <FAIL>", recvbuf);
>> + if(RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
>> + break;
>> + }
>> + } while (msgsock >= 0);
>> + if (msgsock >= 0)
>> + close(msgsock);
>> +
>> + if (!dominfo.paused) {
>> + ret = xc_domain_unpause(xc_handle, domid);
>> + if (ret < 0) {
>> + perror("xc_domain_unpause");
>> + exit(-1);
>> + }
>> + }
>> +
>> + xc_interface_close(xc_handle);
>> + if (ret < 0) {
>> + perror("xc_interface_close");
>> + exit(-1);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-set-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
next prev parent reply other threads:[~2013-10-15 14:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-14 14:07 [PATCH] Add xentrace/xen_crash Don Slutz
2013-10-14 14:11 ` Don Slutz
2013-10-14 15:03 ` Andrew Cooper
2013-10-15 14:53 ` Don Slutz [this message]
2013-10-14 15:13 ` Ian Campbell
2013-10-15 15:25 ` Don Slutz
2013-10-15 15:47 ` Ian Campbell
2013-10-15 16:26 ` Don Slutz
2013-10-14 16:56 ` David Vrabel
2013-10-15 14:50 ` Don Slutz
2013-10-23 17:24 ` Konrad Rzeszutek Wilk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=525D56E8.8050204@terremark.com \
--to=dslutz@verizon.com \
--cc=Don@CloudSwitch.com \
--cc=andrew.cooper3@citrix.com \
--cc=george.dunlap@eu.citrix.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).