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

[Xen-changelog] New memory_op subcall XENMEM_translate_gpfn_list.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] New memory_op subcall XENMEM_translate_gpfn_list.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 16 Feb 2006 19:24:09 +0000
Delivery-date: Thu, 16 Feb 2006 19:37:29 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 0d10fac284274733fe67cf5384fe032508c13766
# Parent  2b0078f771cc1152a003721e20c3972fe7cf6ea8
New memory_op subcall XENMEM_translate_gpfn_list.

Allows translation from GPFNs to MFNs for an auto-translated
guest.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 2b0078f771cc -r 0d10fac28427 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Thu Feb 16 16:37:21 2006
+++ b/tools/libxc/xc_domain.c   Thu Feb 16 17:52:06 2006
@@ -326,6 +326,53 @@
     return err;
 }
 
+int xc_domain_memory_populate_physmap(int xc_handle,
+                                          uint32_t domid,
+                                          unsigned long nr_extents,
+                                          unsigned int extent_order,
+                                          unsigned int address_bits,
+                                          unsigned long *extent_start)
+{
+    int err;
+    struct xen_memory_reservation reservation = {
+        .extent_start = extent_start,
+        .nr_extents   = nr_extents,
+        .extent_order = extent_order,
+        .address_bits = address_bits,
+        .domid        = domid
+    };
+
+    err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
+    if ( err == nr_extents )
+        return 0;
+
+    if ( err > 0 )
+    {
+        fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
+                domid, nr_extents, extent_order);
+        errno = EBUSY;
+        err = -1;
+    }
+
+    return err;
+}
+
+int xc_domain_translate_gpfn_list(int xc_handle,
+                                  uint32_t domid,
+                                  unsigned long nr_gpfns,
+                                  unsigned long *gpfn_list,
+                                  unsigned long *mfn_list)
+{
+    struct xen_translate_gpfn_list op = {
+        .domid        = domid,
+        .nr_gpfns     = nr_gpfns,
+        .gpfn_list    = gpfn_list,
+        .mfn_list     = mfn_list
+    };
+
+    return xc_memory_op(xc_handle, XENMEM_translate_gpfn_list, &op);
+}
+
 int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
 {
     DECLARE_DOM0_OP;
diff -r 2b0078f771cc -r 0d10fac28427 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Thu Feb 16 16:37:21 2006
+++ b/tools/libxc/xc_private.c  Thu Feb 16 17:52:06 2006
@@ -191,6 +191,7 @@
     DECLARE_HYPERCALL;
     struct xen_memory_reservation *reservation = arg;
     struct xen_machphys_mfn_list *xmml = arg;
+    struct xen_translate_gpfn_list *trans = arg;
     long ret = -EINVAL;
 
     hypercall.op     = __HYPERVISOR_memory_op;
@@ -234,6 +235,26 @@
         if ( mlock(arg, sizeof(struct xen_reserved_phys_area)) )
         {
             PERROR("Could not mlock");
+            goto out1;
+        }
+        break;
+    case XENMEM_translate_gpfn_list:
+        if ( mlock(trans, sizeof(*trans)) != 0 )
+        {
+            PERROR("Could not mlock");
+            goto out1;
+        }
+        if ( mlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
+        {
+            PERROR("Could not mlock");
+            safe_munlock(trans, sizeof(*trans));
+            goto out1;
+        }
+        if ( mlock(trans->mfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
+        {
+            PERROR("Could not mlock");
+            safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long));
+            safe_munlock(trans, sizeof(*trans));
             goto out1;
         }
         break;
@@ -258,6 +279,11 @@
         break;
     case XENMEM_reserved_phys_area:
         safe_munlock(arg, sizeof(struct xen_reserved_phys_area));
+        break;
+    case XENMEM_translate_gpfn_list:
+            safe_munlock(trans->mfn_list, trans->nr_gpfns * sizeof(long));
+            safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long));
+            safe_munlock(trans, sizeof(*trans));
         break;
     }
 
diff -r 2b0078f771cc -r 0d10fac28427 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Thu Feb 16 16:37:21 2006
+++ b/tools/libxc/xenctrl.h     Thu Feb 16 17:52:06 2006
@@ -373,6 +373,19 @@
                                           unsigned int extent_order,
                                          unsigned long *extent_start);
 
+int xc_domain_memory_populate_physmap(int xc_handle,
+                                      uint32_t domid,
+                                      unsigned long nr_extents,
+                                      unsigned int extent_order,
+                                      unsigned int address_bits,
+                                      unsigned long *extent_start);
+
+int xc_domain_translate_gpfn_list(int xc_handle,
+                                  uint32_t domid,
+                                  unsigned long nr_gpfns,
+                                  unsigned long *gpfn_list,
+                                  unsigned long *mfn_list);
+
 int xc_domain_ioport_permission(int xc_handle,
                                 uint32_t domid,
                                 uint32_t first_port,
diff -r 2b0078f771cc -r 0d10fac28427 xen/common/memory.c
--- a/xen/common/memory.c       Thu Feb 16 16:37:21 2006
+++ b/xen/common/memory.c       Thu Feb 16 17:52:06 2006
@@ -19,6 +19,13 @@
 #include <asm/current.h>
 #include <asm/hardirq.h>
 #include <public/memory.h>
+
+/*
+ * To allow safe resume of do_memory_op() after preemption, we need to know 
+ * at what point in the page list to resume. For this purpose I steal the 
+ * high-order bits of the @cmd parameter, which are otherwise unused and zero.
+ */
+#define START_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */
 
 static long
 increase_reservation(
@@ -188,17 +195,74 @@
     return nr_extents;
 }
 
-/*
- * To allow safe resume of do_memory_op() after preemption, we need to know 
- * at what point in the page list to resume. For this purpose I steal the 
- * high-order bits of the @cmd parameter, which are otherwise unused and zero.
- */
-#define START_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */
-
-long do_memory_op(int cmd, void *arg)
-{
+static long
+translate_gpfn_list(
+    struct xen_translate_gpfn_list *uop, unsigned long *progress)
+{
+    struct xen_translate_gpfn_list op;
+    unsigned long i, gpfn, mfn;
     struct domain *d;
-    int rc, start_extent, op, flags = 0, preempted = 0;
+
+    if ( copy_from_user(&op, uop, sizeof(op)) )
+        return -EFAULT;
+
+    /* Is size too large for us to encode a continuation? */
+    if ( op.nr_gpfns > (ULONG_MAX >> START_EXTENT_SHIFT) )
+        return -EINVAL;
+
+    if ( !array_access_ok(op.gpfn_list, op.nr_gpfns, sizeof(*op.gpfn_list)) ||
+         !array_access_ok(op.mfn_list, op.nr_gpfns, sizeof(*op.mfn_list)) )
+        return -EFAULT;
+
+    if ( op.domid == DOMID_SELF )
+        op.domid = current->domain->domain_id;
+    else if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( (d = find_domain_by_id(op.domid)) == NULL )
+        return -ESRCH;
+
+    if ( !shadow_mode_translate(d) )
+    {
+        put_domain(d);
+        return -EINVAL;
+    }
+
+    for ( i = *progress; i < op.nr_gpfns; i++ )
+    {
+        if ( hypercall_preempt_check() )
+        {
+            put_domain(d);
+            *progress = i;
+            return -EAGAIN;
+        }
+
+        if ( unlikely(__copy_from_user(&gpfn, &op.gpfn_list[i],
+                                       sizeof(gpfn))) )
+        {
+            put_domain(d);
+            return -EFAULT;
+        }
+
+        mfn = gmfn_to_mfn(d, gpfn);
+
+        if ( unlikely(__copy_to_user(&op.mfn_list[i], &mfn,
+                                     sizeof(mfn))) )
+        {
+            put_domain(d);
+            return -EFAULT;
+        }
+    }
+
+    put_domain(d);
+    return 0;
+}
+
+long do_memory_op(unsigned long cmd, void *arg)
+{
+    struct domain *d;
+    int rc, op, flags = 0, preempted = 0;
+    unsigned long start_extent, progress;
     struct xen_memory_reservation reservation;
     domid_t domid;
 
@@ -211,6 +275,10 @@
     case XENMEM_populate_physmap:
         if ( copy_from_user(&reservation, arg, sizeof(reservation)) )
             return -EFAULT;
+
+        /* Is size too large for us to encode a continuation? */
+        if ( reservation.nr_extents > (ULONG_MAX >> START_EXTENT_SHIFT) )
+            return -EINVAL;
 
         start_extent = cmd >> START_EXTENT_SHIFT;
         if ( unlikely(start_extent > reservation.nr_extents) )
@@ -302,6 +370,16 @@
 
         break;
 
+    case XENMEM_translate_gpfn_list:
+        progress = cmd >> START_EXTENT_SHIFT;
+        rc = translate_gpfn_list(arg, &progress);
+        if ( rc == -EAGAIN )
+            return hypercall2_create_continuation(
+                __HYPERVISOR_memory_op,
+                op | (progress << START_EXTENT_SHIFT),
+                arg);
+        break;
+
     default:
         rc = arch_memory_op(op, arg);
         break;
diff -r 2b0078f771cc -r 0d10fac28427 xen/include/public/memory.h
--- a/xen/include/public/memory.h       Thu Feb 16 16:37:21 2006
+++ b/xen/include/public/memory.h       Thu Feb 16 17:52:06 2006
@@ -101,7 +101,7 @@
  */
 #define XENMEM_reserved_phys_area   7
 typedef struct xen_reserved_phys_area {
-    /* Which request to report about? */
+    /* Which domain to report about? */
     domid_t domid;
 
     /*
@@ -114,6 +114,28 @@
     unsigned long first_gpfn, nr_gpfns;
 } xen_reserved_phys_area_t;
 
+/*
+ * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
+ * code on failure. This call only works for auto-translated guests.
+ */
+#define XENMEM_translate_gpfn_list  8
+typedef struct xen_translate_gpfn_list {
+    /* Which domain to translate for? */
+    domid_t domid;
+
+    /* Length of list. */
+    unsigned long nr_gpfns;
+
+    /* List of GPFNs to translate. */
+    unsigned long *gpfn_list;
+
+    /*
+     * Output list to contain MFN translations. May be the same as the input
+     * list (in which case each input GPFN is overwritten with the output MFN).
+     */
+    unsigned long *mfn_list;
+} xen_translate_gpfn_list_t;
+
 #endif /* __XEN_PUBLIC_MEMORY_H__ */
 
 /*

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] New memory_op subcall XENMEM_translate_gpfn_list., Xen patchbot -unstable <=