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 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.