[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] domctl support for generic memory event handling.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261031275 0
# Node ID 66e29f42247a2f5342d6b748c1e026ebf5dba74e
# Parent  a1ab94c514b80b3f0845465752ed72cfe4fafa73
domctl support for generic memory event handling.

Signed-off-by: Patrick Colp <Patrick.Colp@xxxxxxxxxx>
---
 xen/arch/x86/domctl.c           |   18 +++++++
 xen/arch/x86/mm/mem_event.c     |   91 ++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/mem_event.h |    3 +
 xen/include/public/domctl.h     |   26 +++++++++++
 4 files changed, 138 insertions(+)

diff -r a1ab94c514b8 -r 66e29f42247a xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/arch/x86/domctl.c     Thu Dec 17 06:27:55 2009 +0000
@@ -30,6 +30,8 @@
 #include <asm/hypercall.h> /* for arch_do_domctl */
 #include <xsm/xsm.h>
 #include <xen/iommu.h>
+#include <asm/mem_event.h>
+#include <public/mem_event.h>
 
 #ifdef XEN_GDBSX_CONFIG                    
 #ifdef XEN_KDB_CONFIG
@@ -1299,6 +1301,22 @@ long arch_do_domctl(
     break;
 #endif /* XEN_GDBSX_CONFIG */
 
+    case XEN_DOMCTL_mem_event_op:
+    {
+        struct domain *d;
+
+        ret = -ESRCH;
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            ret = mem_event_domctl(d, &domctl->u.mem_event_op,
+                                   guest_handle_cast(u_domctl, void));
+            rcu_unlock_domain(d);
+            copy_to_guest(u_domctl, domctl, 1);
+        } 
+    }
+    break;
+
     default:
         ret = -ENOSYS;
         break;
diff -r a1ab94c514b8 -r 66e29f42247a xen/arch/x86/mm/mem_event.c
--- a/xen/arch/x86/mm/mem_event.c       Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/arch/x86/mm/mem_event.c       Thu Dec 17 06:27:55 2009 +0000
@@ -188,6 +188,97 @@ int mem_event_check_ring(struct domain *
     return ring_full;
 }
 
+int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec,
+                     XEN_GUEST_HANDLE(void) u_domctl)
+{
+    int rc;
+
+    if ( unlikely(d == current->domain) )
+    {
+        gdprintk(XENLOG_INFO, "Tried to do a memory paging op on itself.\n");
+        return -EINVAL;
+    }
+
+    if ( unlikely(d->is_dying) )
+    {
+        gdprintk(XENLOG_INFO, "Ignoring memory paging op on dying domain %u\n",
+                 d->domain_id);
+        return 0;
+    }
+
+    if ( unlikely(d->vcpu == NULL) || unlikely(d->vcpu[0] == NULL) )
+    {
+        MEM_EVENT_ERROR("Memory paging op on a domain (%u) with no vcpus\n",
+                         d->domain_id);
+        return -EINVAL;
+    }
+
+    /* TODO: XSM hook */
+#if 0
+    rc = xsm_mem_event_control(d, mec->op);
+    if ( rc )
+        return rc;
+#endif
+
+    if ( mec->mode == 0 )
+    {
+        switch( mec->op )
+        {
+        case XEN_DOMCTL_MEM_EVENT_OP_ENABLE:
+        {
+            struct domain *dom_mem_event = current->domain;
+            struct vcpu *v = current;
+            unsigned long ring_addr = mec->ring_addr;
+            unsigned long shared_addr = mec->shared_addr;
+            l1_pgentry_t l1e;
+            unsigned long gfn;
+            p2m_type_t p2mt;
+            mfn_t ring_mfn;
+            mfn_t shared_mfn;
+
+            /* Get MFN of ring page */
+            guest_get_eff_l1e(v, ring_addr, &l1e);
+            gfn = l1e_get_pfn(l1e);
+            ring_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+
+            rc = -EINVAL;
+            if ( unlikely(!mfn_valid(mfn_x(ring_mfn))) )
+                break;
+
+            /* Get MFN of shared page */
+            guest_get_eff_l1e(v, shared_addr, &l1e);
+            gfn = l1e_get_pfn(l1e);
+            shared_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+
+            rc = -EINVAL;
+            if ( unlikely(!mfn_valid(mfn_x(shared_mfn))) )
+                break;
+
+            rc = -EINVAL;
+            if ( mem_event_enable(d, ring_mfn, shared_mfn) != 0 )
+                break;
+
+            rc = 0;
+        }
+        break;
+
+        case XEN_DOMCTL_MEM_EVENT_OP_DISABLE:
+        {
+            rc = mem_event_disable(d);
+        }
+        break;
+
+        default:
+            rc = -ENOSYS;
+            break;
+        }
+    }
+    else
+        rc = -ENOSYS;
+
+    return rc;
+}
+
 
 /*
  * Local variables:
diff -r a1ab94c514b8 -r 66e29f42247a xen/include/asm-x86/mem_event.h
--- a/xen/include/asm-x86/mem_event.h   Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/include/asm-x86/mem_event.h   Thu Dec 17 06:27:55 2009 +0000
@@ -54,6 +54,9 @@ void mem_event_get_response(struct domai
 void mem_event_get_response(struct domain *d, mem_event_response_t *rsp);
 void mem_event_unpause_vcpus(struct domain *d);
 
+int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec,
+                     XEN_GUEST_HANDLE(void) u_domctl);
+
 
 #endif /* __MEM_EVENT_H__ */
 
diff -r a1ab94c514b8 -r 66e29f42247a xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/include/public/domctl.h       Thu Dec 17 06:27:55 2009 +0000
@@ -690,6 +690,31 @@ struct xen_domctl_gdbsx_domstatus {
     uint32_t         vcpu_ev;    /* if yes, what event? */
 
 };
+
+/*
+ * Memory event operations
+ */
+
+#define XEN_DOMCTL_mem_event_op  56
+
+/* Add and remove memory handlers */
+#define XEN_DOMCTL_MEM_EVENT_OP_ENABLE     0
+#define XEN_DOMCTL_MEM_EVENT_OP_DISABLE    1
+
+struct xen_domctl_mem_event_op {
+    uint32_t       op;           /* XEN_DOMCTL_MEM_EVENT_OP_* */
+    uint32_t       mode;         /* XEN_DOMCTL_MEM_EVENT_ENABLE_* */
+
+    /* OP_ENABLE */
+    unsigned long  shared_addr;  /* IN:  Virtual address of shared page */
+    unsigned long  ring_addr;    /* IN:  Virtual address of ring page */
+
+    /* Other OPs */
+    unsigned long  gfn;          /* IN:  gfn of page being operated on */
+};
+typedef struct xen_domctl_mem_event_op xen_domctl_mem_event_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_event_op_t);
+
 
 struct xen_domctl {
     uint32_t cmd;
@@ -734,6 +759,7 @@ struct xen_domctl {
         struct xen_domctl_set_target        set_target;
         struct xen_domctl_subscribe         subscribe;
         struct xen_domctl_debug_op          debug_op;
+        struct xen_domctl_mem_event_op      mem_event_op;
 #if defined(__i386__) || defined(__x86_64__)
         struct xen_domctl_cpuid             cpuid;
 #endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.