Introduce guest_handle_subrange_okay() for checking sub-sections of an
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Jun 2008 12:49:56 +0000 (13:49 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Jun 2008 12:49:56 +0000 (13:49 +0100)
argument array. Needed where a compat shim is splitting up a 32-bit
guest's larger argument array, and only the currently-active part of
the translated array is contained within the compat_arg_xlat_area.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/common/memory.c
xen/include/asm-x86/guest_access.h
xen/include/xen/xencomm.h

index 58f138939fedf9ebd432536e8878800810b0fdd0..eba18fdc3e895628d31273948f02fde5fec56f90 100644 (file)
@@ -47,7 +47,8 @@ static void increase_reservation(struct memop_args *a)
     unsigned int node = domain_to_node(d);
 
     if ( !guest_handle_is_null(a->extent_list) &&
-         !guest_handle_okay(a->extent_list, a->nr_extents) )
+         !guest_handle_subrange_okay(a->extent_list, a->nr_done,
+                                     a->nr_extents-1) )
         return;
 
     if ( (a->extent_order != 0) &&
@@ -94,7 +95,8 @@ static void populate_physmap(struct memop_args *a)
     struct domain *d = a->domain;
     unsigned int node = domain_to_node(d);
 
-    if ( !guest_handle_okay(a->extent_list, a->nr_extents) )
+    if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done,
+                                     a->nr_extents-1) )
         return;
 
     if ( (a->extent_order != 0) &&
@@ -179,7 +181,8 @@ static void decrease_reservation(struct memop_args *a)
     unsigned long i, j;
     xen_pfn_t gmfn;
 
-    if ( !guest_handle_okay(a->extent_list, a->nr_extents) )
+    if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done,
+                                     a->nr_extents-1) )
         return;
 
     for ( i = a->nr_done; i < a->nr_extents; i++ )
@@ -219,8 +222,8 @@ static long translate_gpfn_list(
     if ( op.nr_gpfns > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) )
         return -EINVAL;
 
-    if ( !guest_handle_okay(op.gpfn_list, op.nr_gpfns) ||
-         !guest_handle_okay(op.mfn_list,  op.nr_gpfns) )
+    if ( !guest_handle_subrange_okay(op.gpfn_list, *progress, op.nr_gpfns-1) ||
+         !guest_handle_subrange_okay(op.mfn_list, *progress, op.nr_gpfns-1) )
         return -EFAULT;
 
     if ( op.domid == DOMID_SELF )
index 75f1f3097d7afc303295cd863900ed90fc78fd92..a8f111ae9b8c8c90af316f083a3454d113e727ee 100644 (file)
 #define guest_handle_okay(hnd, nr)                      \
     (shadow_mode_external(current->domain) ||           \
      array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)))
+#define guest_handle_subrange_okay(hnd, first, last)    \
+    (shadow_mode_external(current->domain) ||           \
+     array_access_ok((hnd).p + (first),                 \
+                     (last)-(first)+1,                  \
+                     sizeof(*(hnd).p)))
 
 #define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
     const typeof(*(ptr)) *_s = (ptr);                   \
index f044c74f99e4623f11b21fe3c0e04af4d74531db..bce2ca720d3895b0bee3d70144c639d9cb673e09 100644 (file)
@@ -62,6 +62,7 @@ static inline unsigned long xencomm_inline_addr(const void *handle)
 /* Since we run in real mode, we can safely access all addresses. That also
  * means our __routines are identical to our "normal" routines. */
 #define guest_handle_okay(hnd, nr) 1
+#define guest_handle_subrange_okay(hnd, first, last) 1
 
 /*
  * Copy an array of objects to guest context via a guest handle.