WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] mem_access test tool: xen-access

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] mem_access test tool: xen-access
From: Joe Epstein <jepstein98@xxxxxxxxx>
Date: Fri, 7 Jan 2011 10:12:01 -0800
Delivery-date: Fri, 07 Jan 2011 10:18:04 -0800
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:mime-version:received:from:date :message-id:subject:to:content-type; bh=RoIBvEtmPRBKZ/tXioN3id3AmdTyoiF0kfFaskXbpM0=; b=Z1OArQxcNAh122kjo4pgeEytLm1YO9JXwcNyhoSckF52MgJPBxO5TqmdouQPPv1rk+ B6J48OJSLxAShV69vWnSULAze6BseS038LGNoseQACAD9uipdDzIbdO1rLwo9+fss7Di EsekX59mbnBnVqu0vSPdQt3BLkN/vSOw+ASek=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; b=t0bOiPcNNFVJSaoEHsqpU9CzHL+JJmZoqq86zSH4mCW7EEGeiplAAi6v6Z3t5yXe0X vO2Ywq1eqXL1bWCQyXyE/0N3TWRUP8GG4X/0cQgO/wR3TpT77Isq0jUVFak8mYKYGCsT rqeNgI2SK8uYOGPQmCObpEAckDABEP2gzUtHs=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Added a test tool to let the memory access APIs be tested.  This tool logs to stdout the memory accesses that the domain given is performing.  

Signed-off-by: Joe Epstein <jepstein98@xxxxxxxxx>


diff -r 2c4c77b64b02 -r 378fba25130d tools/misc/Makefile
--- a/tools/misc/Makefile    Wed Jan 05 19:36:17 2011 -0800
+++ b/tools/misc/Makefile    Fri Jan 07 10:02:16 2011 -0800
@@ -11,7 +11,7 @@ CFLAGS   += $(INCLUDES)
 HDRS     = $(wildcard *.h)
 
 TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd
-TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash
+TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash xen-access
 TARGETS-$(CONFIG_MIGRATE) += xen-hptool
 TARGETS := $(TARGETS-y)
 
@@ -24,7 +24,7 @@ INSTALL_BIN-$(CONFIG_X86) += xen-detect
 INSTALL_BIN := $(INSTALL_BIN-y)
 
 INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd
-INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash
+INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash xen-access
 INSTALL_SBIN-$(CONFIG_MIGRATE) += xen-hptool
 INSTALL_SBIN := $(INSTALL_SBIN-y)
 
@@ -51,7 +51,7 @@ clean:
 %.o: %.c $(HDRS) Makefile
     $(CC) -c $(CFLAGS) -o $@ $<
 
-xen-hvmctx xen-hvmcrash xenperf xenpm gtracestat xenlockprof xen-hptool xenwatchdogd: %: %.o Makefile
+xen-hvmctx xen-hvmcrash xenperf xenpm gtracestat xenlockprof xen-hptool xenwatchdogd xen-access: %: %.o Makefile
     $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore)
 
 gtraceview: %: %.o Makefile
diff -r 2c4c77b64b02 -r 378fba25130d tools/misc/xen-access.c
--- /dev/null    Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/misc/xen-access.c    Fri Jan 07 10:02:16 2011 -0800
@@ -0,0 +1,668 @@
+/*
+ * xen-access.c
+ *
+ * Exercises the basic per-page access mechanisms
+ *
+ * Copyright (c) 2011 Virtuata, Inc.
+ * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp), based on
+ *   xenpaging.c
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <xc_private.h>
+#include <xg_save_restore.h>
+
+#include <xen/mem_event.h>
+
+//#if 0
+#undef DPRINTF
+#define DPRINTF(a, b...) fprintf(stderr, a, ## b)
+//#endif
+
+/* Spinlock and mem event definitions */
+
+#define SPIN_LOCK_UNLOCKED 0
+
+#define ADDR (*(volatile long *) addr)
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_set_bit(int nr, volatile void *addr)
+{
+    int oldbit;
+
+    asm volatile (
+        "btsl %2,%1\n\tsbbl %0,%0"
+        : "=r" (oldbit), "=m" (ADDR)
+        : "Ir" (nr), "m" (ADDR) : "memory");
+    return oldbit;
+}
+
+typedef int spinlock_t;
+
+static inline void spin_lock(spinlock_t *lock)
+{
+    while ( test_and_set_bit(1, lock) );
+}
+
+static inline void spin_lock_init(spinlock_t *lock)
+{
+    *lock = SPIN_LOCK_UNLOCKED;
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+    *lock = SPIN_LOCK_UNLOCKED;
+}
+
+static inline int spin_trylock(spinlock_t *lock)
+{
+    return !test_and_set_bit(1, lock);
+}
+
+#define mem_event_ring_lock_init(_m)  spin_lock_init(&(_m)->ring_lock)
+#define mem_event_ring_lock(_m)       spin_lock(&(_m)->ring_lock)
+#define mem_event_ring_unlock(_m)     spin_unlock(&(_m)->ring_lock)
+
+typedef struct mem_event {
+    domid_t domain_id;
+    xc_evtchn *xce_handle;
+    int port;
+    mem_event_back_ring_t back_ring;
+    mem_event_shared_page_t *shared_page;
+    void *ring_page;
+    spinlock_t ring_lock;
+} mem_event_t;
+
+typedef struct xc_platform_info {
+    unsigned long max_mfn;
+    unsigned long hvirt_start;
+    unsigned int  pt_levels;
+    unsigned int  guest_width;
+} xc_platform_info_t;
+
+typedef struct xenaccess {
+    xc_interface *xc_handle;
+
+    xc_platform_info_t *platform_info;
+    xc_domaininfo_t    *domain_info;
+
+    mem_event_t mem_event;
+} xenaccess_t;
+
+static int interrupted;
+
+static void close_handler(int sig)
+{
+    interrupted = sig;
+}
+
+int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms)
+{
+    struct pollfd fd = { .fd = xc_evtchn_fd(xce), .events = POLLIN | POLLERR };
+    int port;
+    int rc;
+
+    rc = poll(&fd, 1, ms);
+    if ( rc == -1 )
+    {
+        if (errno == EINTR)
+            return 0;
+
+        ERROR("Poll exited with an error");
+        goto err;
+    }
+
+    if ( rc == 1 )
+    {
+        port = xc_evtchn_pending(xce);
+        if ( port == -1 )
+        {
+            ERROR("Failed to read port from event channel");
+            goto err;
+        }
+
+        rc = xc_evtchn_unmask(xce, port);
+        if ( rc != 0 )
+        {
+            ERROR("Failed to unmask event channel port");
+            goto err;
+        }
+    }
+    else
+        port = -1;
+
+    return port;
+
+ err:
+    return -errno;
+}
+
+static void *init_page(void)
+{
+    void *buffer;
+    int ret;
+
+    /* Allocated page memory */
+    ret = posix_memalign(&buffer, PAGE_SIZE, PAGE_SIZE);
+    if ( ret != 0 )
+        goto out_alloc;
+
+    /* Lock buffer in memory so it can't be paged out */
+    ret = mlock(buffer, PAGE_SIZE);
+    if ( ret != 0 )
+        goto out_lock;
+
+    return buffer;
+
+    munlock(buffer, PAGE_SIZE);
+ out_lock:
+    free(buffer);
+ out_alloc:
+    return NULL;
+}
+
+xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
+{
+    xenaccess_t *xenaccess;
+    xc_interface *xch;
+    int rc;
+
+    xch = xc_interface_open(NULL, NULL, 0);
+    if ( !xch )
+        goto err_iface;
+
+    DPRINTF("xenaccess init\n");
+    *xch_r = xch;
+
+    /* Allocate memory */
+    xenaccess = malloc(sizeof(xenaccess_t));
+    memset(xenaccess, 0, sizeof(xenaccess_t));
+
+    /* Open connection to xen */
+    xenaccess->xc_handle = xch;
+
+    /* Set domain id */
+    xenaccess->mem_event.domain_id = domain_id;
+
+    /* Initialise shared page */
+    xenaccess->mem_event.shared_page = init_page();
+    if ( xenaccess->mem_event.shared_page == NULL )
+    {
+        ERROR("Error initialising shared page");
+        goto err;
+    }
+
+    /* Initialise ring page */
+    xenaccess->mem_event.ring_page = init_page();
+    if ( xenaccess->mem_event.ring_page == NULL )
+    {
+        ERROR("Error initialising ring page");
+        goto err;
+    }
+
+
+    /* Initialise ring */
+    SHARED_RING_INIT((mem_event_sring_t *)xenaccess->mem_event.ring_page);
+    BACK_RING_INIT(&xenaccess->mem_event.back_ring,
+                   (mem_event_sring_t *)xenaccess->mem_event.ring_page,
+                   PAGE_SIZE);
+
+    /* Initialise lock */
+    mem_event_ring_lock_init(&xenaccess->mem_event);
+
+    /* Initialise Xen */
+    rc = xc_mem_event_enable(xenaccess->xc_handle, xenaccess->mem_event.domain_id,
+                             xenaccess->mem_event.shared_page,
+                             xenaccess->mem_event.ring_page);
+    if ( rc != 0 )
+    {
+        switch ( errno ) {
+            case EBUSY:
+                ERROR("xenaccess is (or was) active on this domain");
+                break;
+            case ENODEV:
+                ERROR("EPT not supported for this guest");
+                break;
+            default:
+                perror("Error initialising shared page");
+                break;
+        }
+        goto err;
+    }
+
+    /* Open event channel */
+    xenaccess->mem_event.xce_handle = xc_evtchn_open(NULL, 0);
+    if ( xenaccess->mem_event.xce_handle == NULL )
+    {
+        ERROR("Failed to open event channel");
+        goto err;
+    }
+
+    /* Bind event notification */
+    rc = xc_evtchn_bind_interdomain(xenaccess->mem_event.xce_handle,
+                                    xenaccess->mem_event.domain_id,
+                                    xenaccess->mem_event.shared_page->port);
+    if ( rc < 0 )
+    {
+        ERROR("Failed to bind event channel");
+        goto err;
+    }
+
+    xenaccess->mem_event.port = rc;
+
+    /* Get platform info */
+    xenaccess->platform_info = malloc(sizeof(xc_platform_info_t));
+    if ( xenaccess->platform_info == NULL )
+    {
+        ERROR("Error allocating memory for platform info");
+        goto err;
+    }
+
+    rc = get_platform_info(xenaccess->xc_handle, domain_id,
+                           &xenaccess->platform_info->max_mfn,
+                           &xenaccess->platform_info->hvirt_start,
+                           &xenaccess->platform_info->pt_levels,
+                           &xenaccess->platform_info->guest_width);
+    if ( rc != 1 )
+    {
+        ERROR("Error getting platform info");
+        goto err;
+    }
+
+    /* Get domaininfo */
+    xenaccess->domain_info = malloc(sizeof(xc_domaininfo_t));
+    if ( xenaccess->domain_info == NULL )
+    {
+        ERROR("Error allocating memory for domain info");
+        goto err;
+    }
+
+    rc = xc_domain_getinfolist(xenaccess->xc_handle, domain_id, 1,
+                               xenaccess->domain_info);
+    if ( rc != 1 )
+    {
+        ERROR("Error getting domain info");
+        goto err;
+    }
+
+    DPRINTF("max_pages = %"PRIx64"\n", xenaccess->domain_info->max_pages);
+
+    return xenaccess;
+
+ err:
+    if ( xenaccess )
+    {
+        if ( xenaccess->mem_event.shared_page )
+        {
+            munlock(xenaccess->mem_event.shared_page, PAGE_SIZE);
+            free(xenaccess->mem_event.shared_page);
+        }
+
+        if ( xenaccess->mem_event.ring_page )
+        {
+            munlock(xenaccess->mem_event.ring_page, PAGE_SIZE);
+            free(xenaccess->mem_event.ring_page);
+        }
+
+        free(xenaccess->platform_info);
+        free(xenaccess->domain_info);
+        free(xenaccess);
+    }
+
+ err_iface:
+    return NULL;
+}
+
+int xenaccess_teardown(xc_interface *xch, xenaccess_t *xenaccess)
+{
+    int rc;
+
+    if ( xenaccess == NULL )
+        return 0;
+
+    /* Tear down domain xenaccess in Xen */
+    rc = xc_mem_event_disable(xenaccess->xc_handle, xenaccess->mem_event.domain_id);
+    if ( rc != 0 )
+    {
+        ERROR("Error tearing down domain xenaccess in xen");
+    }
+
+    /* Unbind VIRQ */
+    rc = xc_evtchn_unbind(xenaccess->mem_event.xce_handle, xenaccess->mem_event.port);
+    if ( rc != 0 )
+    {
+        ERROR("Error unbinding event port");
+    }
+    xenaccess->mem_event.port = -1;
+
+    /* Close event channel */
+    rc = xc_evtchn_close(xenaccess->mem_event.xce_handle);
+    if ( rc != 0 )
+    {
+        ERROR("Error closing event channel");
+    }
+    xenaccess->mem_event.xce_handle = NULL;
+
+    /* Close connection to Xen */
+    rc = xc_interface_close(xenaccess->xc_handle);
+    if ( rc != 0 )
+    {
+        ERROR("Error closing connection to xen");
+    }
+    xenaccess->xc_handle = NULL;
+
+    return 0;
+}
+
+int get_request(mem_event_t *mem_event, mem_event_request_t *req)
+{
+    mem_event_back_ring_t *back_ring;
+    RING_IDX req_cons;
+
+    mem_event_ring_lock(mem_event);
+
+    back_ring = &mem_event->back_ring;
+    req_cons = back_ring->req_cons;
+
+    /* Copy request */
+    memcpy(req, RING_GET_REQUEST(back_ring, req_cons), sizeof(*req));
+    req_cons++;
+
+    /* Update ring */
+    back_ring->req_cons = req_cons;
+    back_ring->sring->req_event = req_cons + 1;
+
+    mem_event_ring_unlock(mem_event);
+
+    return 0;
+}
+
+static int put_response(mem_event_t *mem_event, mem_event_response_t *rsp)
+{
+    mem_event_back_ring_t *back_ring;
+    RING_IDX rsp_prod;
+
+    mem_event_ring_lock(mem_event);
+
+    back_ring = &mem_event->back_ring;
+    rsp_prod = back_ring->rsp_prod_pvt;
+
+    /* Copy response */
+    memcpy(RING_GET_RESPONSE(back_ring, rsp_prod), rsp, sizeof(*rsp));
+    rsp_prod++;
+
+    /* Update ring */
+    back_ring->rsp_prod_pvt = rsp_prod;
+    RING_PUSH_RESPONSES(back_ring);
+
+    mem_event_ring_unlock(mem_event);
+
+    return 0;
+}
+
+static int xenaccess_resume_page(xenaccess_t *paging, mem_event_response_t *rsp)
+{
+    int ret;
+
+    /* Put the page info on the ring */
+    ret = put_response(&paging->mem_event, rsp);
+    if ( ret != 0 )
+        goto out;
+
+    /* Tell Xen page is ready */
+    ret = xc_mem_access_resume(paging->xc_handle, paging->mem_event.domain_id,
+                               rsp->gfn);
+    ret = xc_evtchn_notify(paging->mem_event.xce_handle,
+                           paging->mem_event.port);
+
+ out:
+    return ret;
+}
+
+void usage(char* progname)
+{
+    fprintf(stderr,
+            "Usage: %s [-m] <domain_id> write|exec|int3\n"
+            "\n"
+            "Logs first page writes, execs, or int3 traps that occur on the domain.\n"
+            "\n"
+            "-m requires this program to run, or else the domain may pause\n",
+            progname);
+}
+
+int main(int argc, char *argv[])
+{
+    struct sigaction act;
+    domid_t domain_id;
+    xenaccess_t *xenaccess;
+    mem_event_request_t req;
+    mem_event_response_t rsp;
+    int rc = -1;
+    int rc1;
+    xc_interface *xch;
+    hvmmem_access_t default_access = HVMMEM_access_rwx;
+    hvmmem_access_t after_first_access = HVMMEM_access_rwx;
+    int required = 0;
+    int int3 = 0;
+    int shutting_down = 0;
+
+    char* progname = argv[0];
+    argv++;
+    argc--;
+
+    if ( argc == 3 && argv[0][0] == '-' )
+    {
+        argv++;
+        argc--;
+
+        if ( !strcmp(argv[0], "-m") )
+            required = 1;
+        else
+        {
+            usage(progname);
+            return -1;
+        }
+    }
+
+    if ( argc != 2 )
+    {
+        usage(progname);
+        return -1;
+    }
+
+    domain_id = atoi(argv[0]);
+    argv++;
+    argc--;
+
+    if ( !strcmp(argv[0], "write") )
+    {
+        default_access = HVMMEM_access_rx;
+        after_first_access = HVMMEM_access_rwx;
+    }
+    else if ( !strcmp(argv[0], "exec") )
+    {
+        default_access = HVMMEM_access_rw;
+        after_first_access = HVMMEM_access_rwx;
+    }
+    else if ( !strcmp(argv[0], "int3") )
+    {
+        int3 = 1;
+    }
+    else
+    {
+        usage(argv[0]);
+        return -1;
+    }
+
+    xenaccess = xenaccess_init(&xch, domain_id);
+    if ( xenaccess == NULL )
+    {
+        ERROR("Error initialising xenaccess");
+        return 1;
+    }
+
+    DPRINTF("starting %s %u\n", argv[0], domain_id);
+
+    /* ensure that if we get a signal, we'll do cleanup, then exit */
+    act.sa_handler = close_handler;
+    act.sa_flags = 0;
+    sigemptyset(&act.sa_mask);
+    sigaction(SIGHUP,  &act, NULL);
+    sigaction(SIGTERM, &act, NULL);
+    sigaction(SIGINT,  &act, NULL);
+    sigaction(SIGALRM, &act, NULL);
+
+    /* Set whether the access listener is required */
+    xc_domain_set_access_required(xch, domain_id, required);
+
+    /* Set the default access type and convert all pages to it */
+    rc = xc_hvm_set_mem_access(xch, domain_id, default_access, ~0ull, 0);
+    rc = xc_hvm_set_mem_access(xch, domain_id, default_access, 0, xenaccess->domain_info->max_pages);
+
+    if ( int3 )
+        rc = xc_set_hvm_param(xch, domain_id, HVM_PARAM_MEMORY_EVENT_INT3, HVMPME_mode_sync);
+    else
+        rc = xc_set_hvm_param(xch, domain_id, HVM_PARAM_MEMORY_EVENT_INT3, HVMPME_mode_disabled);
+
+    /* Wait for access */
+    for (;;)
+    {
+        if ( interrupted )
+        {
+            DPRINTF("xenaccess shutting down on signal %d\n", interrupted);
+
+            /* Unregister for every event */
+            rc = xc_hvm_set_mem_access(xch, domain_id, HVMMEM_access_rwx, ~0ull, 0);
+            rc = xc_hvm_set_mem_access(xch, domain_id, HVMMEM_access_rwx, 0, xenaccess->domain_info->max_pages);
+            rc = xc_set_hvm_param(xch, domain_id, HVM_PARAM_MEMORY_EVENT_INT3, HVMPME_mode_disabled);
+
+            shutting_down = 1;
+        }
+
+        rc = xc_wait_for_event_or_timeout(xch, xenaccess->mem_event.xce_handle, 100);
+        if ( rc < -1 )
+        {
+            ERROR("Error getting event");
+            interrupted = -1;
+            continue;
+        }
+        else if ( rc != -1 )
+        {
+            DPRINTF("Got event from Xen\n");
+        }
+
+        while ( RING_HAS_UNCONSUMED_REQUESTS(&xenaccess->mem_event.back_ring) )
+        {
+            hvmmem_access_t access;
+
+            rc = get_request(&xenaccess->mem_event, &req);
+            if ( rc != 0 )
+            {
+                ERROR("Error getting request");
+                interrupted = -1;
+                continue;
+            }
+
+            memset( &rsp, 0, sizeof (rsp) );
+            rsp.vcpu_id = req.vcpu_id;
+            rsp.flags = req.flags;
+
+            switch (req.reason) {
+            case MEM_EVENT_REASON_VIOLATION:
+                rc = xc_hvm_get_mem_access(xch, domain_id, req.gfn, &access);
+
+                printf("PAGE ACCESS: %c%c%c for GFN %lx (offset %06lx) gla %016lx (vcpu %d)\n",
+                        req.access_r ? 'r' : '-',
+                        req.access_w ? 'w' : '-',
+                        req.access_x ? 'x' : '-',
+                        req.gfn,
+                        req.offset,
+                        req.gla,
+                        req.vcpu_id);
+
+                if ( default_access != after_first_access )
+                    rc = xc_hvm_set_mem_access(xch, domain_id, after_first_access, req.gfn, 1);
+
+
+                rsp.gfn = req.gfn;
+                rsp.p2mt = req.p2mt;
+                break;
+            case MEM_EVENT_REASON_INT3:
+                printf("INT3: rip=%016lx, gfn=%lx (vcpu %d)\n", req.gla, req.gfn,
+                        req.vcpu_id);
+
+                /* Reinject */
+                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id, 3, -1, 0);
+
+                break;
+            default:
+                fprintf(stderr, "UNKNOWN REASON CODE %d\n", req.reason);
+            }
+
+            rc = xenaccess_resume_page(xenaccess, &rsp);
+            if ( rc != 0 )
+            {
+                ERROR("Error resuming page");
+                interrupted = -1;
+                continue;
+            }
+        }
+
+        if ( shutting_down )
+            break;
+    }
+    DPRINTF("xenaccess shut down on signal %d\n", interrupted);
+
+    /* Tear down domain xenaccess */
+    rc1 = xenaccess_teardown(xch, xenaccess);
+    if ( rc1 != 0 )
+        ERROR("Error tearing down xenaccess");
+
+    if ( rc == 0 )
+        rc = rc1;
+
+    xc_interface_close(xch);
+
+    DPRINTF("xenaccess exit code %d\n", rc);
+    return rc;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */

Attachment: xen-access.patch
Description: Text Data

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] mem_access test tool: xen-access, Joe Epstein <=