libxc: make do_memory_op's callers responsible for locking indirect buffers
authorIan Campbell <ian.campbell@citrix.com>
Mon, 18 Oct 2010 16:36:46 +0000 (17:36 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Mon, 18 Oct 2010 16:36:46 +0000 (17:36 +0100)
Push responsibility for locking buffers refered to by the memory_op
argument up into the callers (which are now all internal to libxc).

This removes the last of the introspecation from do_memory_op and
generally makes the transistion to hypercall buffers smoother.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxc/xc_domain.c
tools/libxc/xc_private.c

index 2de70c1c608164476b992d85247802634ceaac34..56de488b5e5f8b859fcf16b0439932c534c391d5 100644 (file)
@@ -599,10 +599,19 @@ int xc_domain_increase_reservation(xc_interface *xch,
     };
 
     /* may be NULL */
+    if ( extent_start && lock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)) != 0 )
+    {
+        PERROR("Could not lock memory for XENMEM_increase_reservation hypercall");
+        return -1;
+    }
+
     set_xen_guest_handle(reservation.extent_start, extent_start);
 
     err = do_memory_op(xch, XENMEM_increase_reservation, &reservation, sizeof(reservation));
 
+    if ( extent_start )
+        unlock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t));
+
     return err;
 }
 
@@ -647,7 +656,11 @@ int xc_domain_decrease_reservation(xc_interface *xch,
         .domid        = domid
     };
 
-    set_xen_guest_handle(reservation.extent_start, extent_start);
+    if ( lock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)) != 0 )
+    {
+        PERROR("Could not lock memory for XENMEM_decrease_reservation hypercall");
+        return -1;
+    }
 
     if ( extent_start == NULL )
     {
@@ -656,8 +669,12 @@ int xc_domain_decrease_reservation(xc_interface *xch,
         return -1;
     }
 
+    set_xen_guest_handle(reservation.extent_start, extent_start);
+
     err = do_memory_op(xch, XENMEM_decrease_reservation, &reservation, sizeof(reservation));
 
+    unlock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t));
+
     return err;
 }
 
@@ -715,10 +732,19 @@ int xc_domain_populate_physmap(xc_interface *xch,
         .mem_flags    = mem_flags,
         .domid        = domid
     };
+
+    if ( lock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)) != 0 )
+    {
+        PERROR("Could not lock memory for XENMEM_populate_physmap hypercall");
+        return -1;
+    }
+
     set_xen_guest_handle(reservation.extent_start, extent_start);
 
     err = do_memory_op(xch, XENMEM_populate_physmap, &reservation, sizeof(reservation));
 
+    unlock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t));
+
     return err;
 }
 
index 8ce66c54403c8cca013451721c35aceb4ccbb4b6..f2ff93ad2658ba5e534a10f862f2b1d107d849ea 100644 (file)
@@ -424,9 +424,6 @@ int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
 int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len)
 {
     DECLARE_HYPERCALL;
-    struct xen_memory_reservation *reservation = arg;
-    struct xen_machphys_mfn_list *xmml = arg;
-    xen_pfn_t *extent_start;
     long ret = -EINVAL;
 
     hypercall.op     = __HYPERVISOR_memory_op;
@@ -439,69 +436,11 @@ int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len)
         goto out1;
     }
 
-    switch ( cmd )
-    {
-    case XENMEM_increase_reservation:
-    case XENMEM_decrease_reservation:
-    case XENMEM_populate_physmap:
-        get_xen_guest_handle(extent_start, reservation->extent_start);
-        if ( (extent_start != NULL) &&
-             (lock_pages(xch, extent_start,
-                    reservation->nr_extents * sizeof(xen_pfn_t)) != 0) )
-        {
-            PERROR("Could not lock");
-            unlock_pages(xch, reservation, sizeof(*reservation));
-            goto out1;
-        }
-        break;
-    case XENMEM_machphys_mfn_list:
-        get_xen_guest_handle(extent_start, xmml->extent_start);
-        if ( lock_pages(xch, extent_start,
-                   xmml->max_extents * sizeof(xen_pfn_t)) != 0 )
-        {
-            PERROR("Could not lock");
-            unlock_pages(xch, xmml, sizeof(*xmml));
-            goto out1;
-        }
-        break;
-    case XENMEM_add_to_physmap:
-    case XENMEM_current_reservation:
-    case XENMEM_maximum_reservation:
-    case XENMEM_maximum_gpfn:
-    case XENMEM_set_pod_target:
-    case XENMEM_get_pod_target:
-        break;
-    }
-
     ret = do_xen_hypercall(xch, &hypercall);
 
     if ( len )
         unlock_pages(xch, arg, len);
 
-    switch ( cmd )
-    {
-    case XENMEM_increase_reservation:
-    case XENMEM_decrease_reservation:
-    case XENMEM_populate_physmap:
-        get_xen_guest_handle(extent_start, reservation->extent_start);
-        if ( extent_start != NULL )
-            unlock_pages(xch, extent_start,
-                         reservation->nr_extents * sizeof(xen_pfn_t));
-        break;
-    case XENMEM_machphys_mfn_list:
-        get_xen_guest_handle(extent_start, xmml->extent_start);
-        unlock_pages(xch, extent_start,
-                     xmml->max_extents * sizeof(xen_pfn_t));
-        break;
-    case XENMEM_add_to_physmap:
-    case XENMEM_current_reservation:
-    case XENMEM_maximum_reservation:
-    case XENMEM_maximum_gpfn:
-    case XENMEM_set_pod_target:
-    case XENMEM_get_pod_target:
-        break;
-    }
-
  out1:
     return ret;
 }
@@ -534,11 +473,23 @@ int xc_machphys_mfn_list(xc_interface *xch,
     struct xen_machphys_mfn_list xmml = {
         .max_extents = max_extents,
     };
+
+    if ( lock_pages(xch, extent_start, max_extents * sizeof(xen_pfn_t)) != 0 )
+    {
+        PERROR("Could not lock memory for XENMEM_machphys_mfn_list hypercall");
+        return -1;
+    }
+
     set_xen_guest_handle(xmml.extent_start, extent_start);
     rc = do_memory_op(xch, XENMEM_machphys_mfn_list, &xmml, sizeof(xmml));
     if (rc || xmml.nr_extents != max_extents)
-        return -1;
-    return 0;
+        rc = -1;
+    else
+        rc = 0;
+
+    unlock_pages(xch, extent_start, max_extents * sizeof(xen_pfn_t));
+
+    return rc;
 }
 
 #ifndef __ia64__