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 6 of 8] Implement sub-page grant support

# HG changeset patch
# User Steven Smith <steven.smith@xxxxxxxxxxxxx>
# Date 1222085347 -3600
# Node ID e9b623fd710f2130bcb925161abe26c6980b91c3
# Parent  842baf721920b032f358ad326145817b42d053a1
Implement sub-page grant support.

Signed-off-by: Steven Smith <steven.smith@xxxxxxxxxx>

diff -r 842baf721920 -r e9b623fd710f xen/common/grant_table.c
--- a/xen/common/grant_table.c  Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/common/grant_table.c  Mon Sep 22 13:09:07 2008 +0100
@@ -210,6 +210,7 @@
 
 static int _set_status_v1(domid_t  domid,
                           int readonly,
+                          int mapflag,
                           grant_entry_header_t *shah, 
                           struct active_grant_entry *act)
 {
@@ -226,6 +227,11 @@
      * so we allow a few retries before failing.
      */
     int retries = 0;
+
+    /* if this is a grant mapping operation we should ensure GTF_sub_page
+       is not set */
+    if (mapflag)
+        mask |= GTF_sub_page;
 
     scombo.word = *(u32 *)shah;
 
@@ -276,6 +282,7 @@
 
 static int _set_status_v2(domid_t  domid,
                           int readonly,
+                          int mapflag,
                           grant_entry_header_t *shah, 
                           struct active_grant_entry *act,
                           grant_status_t *status)
@@ -294,6 +301,11 @@
                   it back into two reads */
     flags = scombo.shorts.flags;
     id = scombo.shorts.domid;
+
+    /* if this is a grant mapping operation we should ensure GTF_sub_page
+       is not set */
+    if (mapflag)
+        mask |= GTF_sub_page;
 
     /* If not already pinned, check the grant domid and type. */
     if ( !act->pin &&
@@ -355,15 +367,16 @@
 static int _set_status(unsigned gt_version,
                        domid_t  domid,
                        int readonly,
+                       int mapflag,
                        grant_entry_header_t *shah,
                        struct active_grant_entry *act,
                        grant_status_t *status)
 {
 
     if (gt_version == 1)
-        return _set_status_v1(domid, readonly, shah, act);
+        return _set_status_v1(domid, readonly, mapflag, shah, act);
     else
-        return _set_status_v2(domid, readonly, shah, act, status);
+        return _set_status_v2(domid, readonly, mapflag, shah, act, status);
 }
 
 /*
@@ -460,10 +473,11 @@
     /* If already pinned, check the active domid and avoid refcnt overflow. */
     if ( act->pin &&
          ((act->domid != ld->domain_id) ||
-          (act->pin & 0x80808080U) != 0) )
+          (act->pin & 0x80808080U) != 0 ||
+          (act->is_sub_page)) )
         PIN_FAIL(unlock_out, GNTST_general_error,
-                 "Bad domain (%d != %d), or risk of counter overflow %08x\n",
-                 act->domid, ld->domain_id, act->pin);
+                 "Bad domain (%d != %d), or risk of counter overflow %08x, or 
subpage %d\n",
+                 act->domid, ld->domain_id, act->pin, act->is_sub_page);
 
     if ( !act->pin ||
          (!(op->flags & GNTMAP_readonly) &&
@@ -471,7 +485,7 @@
     {
         if ( (rc = _set_status(rd->grant_table->gt_version,
                                ld->domain_id, op->flags & GNTMAP_readonly,
-                               shah, act, status) ) != GNTST_okay )
+                               1, shah, act, status) ) != GNTST_okay )
              goto unlock_out;
 
         if ( !act->pin )
@@ -482,6 +496,9 @@
             else
                 act->gfn = sha2->full_page.frame;
             act->frame = gmfn_to_mfn(rd, act->gfn);
+            act->start = 0;
+            act->length = PAGE_SIZE;
+            act->is_sub_page = 0;
         }
     }
 
@@ -1554,7 +1571,7 @@
 static int
 __acquire_grant_for_copy(
     struct domain *rd, unsigned long gref, int readonly,
-    unsigned long *frame)
+    unsigned long *frame, unsigned *page_off, unsigned *length)
 {
     grant_entry_v1_t *sha1;
     grant_entry_v2_t *sha2;
@@ -1601,21 +1618,40 @@
     {
         if ( (rc = _set_status(rd->grant_table->gt_version,
                                current->domain->domain_id, 
-                               readonly, shah, act, status) ) != GNTST_okay )
+                               readonly, 0, shah, act, status) ) != GNTST_okay 
)
              goto unlock_out;
+
         if ( !act->pin )
         {
             act->domid = current->domain->domain_id;
+            act->is_sub_page = 0;
+            act->start = 0;
+            act->length = PAGE_SIZE;
+
             if ( sha1 )
+            {
                 act->gfn = sha1->frame;
+            }
+            else if ( shah->flags & GTF_sub_page )
+            {
+                act->start = sha2->sub_page.page_off;
+                act->length = sha2->sub_page.length;
+                act->is_sub_page = 1;
+                act->gfn = sha2->sub_page.frame;
+            }
             else
+            {
                 act->gfn = sha2->full_page.frame;
+            }
+
             act->frame = gmfn_to_mfn(rd, act->gfn);
         }
     }
 
     act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc;
 
+    *page_off = act->start;
+    *length = act->length;
     *frame = act->frame;
 
  unlock_out:
@@ -1667,10 +1703,18 @@
 
     if ( src_is_gref )
     {
-        rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame);
+        unsigned source_off, source_len;
+        rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame,
+                                      &source_off, &source_len);
         if ( rc != GNTST_okay )
             goto error_out;
         have_s_grant = 1;
+        if ( op->source.offset < source_off ||
+             op->len > source_len )
+            PIN_FAIL(error_out, GNTST_general_error,
+                     "copy source out of bounds: %d < %d || %d > %d\n",
+                     op->source.offset, source_off,
+                     op->len, source_len);
     }
     else
     {
@@ -1690,10 +1734,18 @@
 
     if ( dest_is_gref )
     {
-        rc = __acquire_grant_for_copy(dd, op->dest.u.ref, 0, &d_frame);
+        unsigned dest_off, dest_len;
+        rc = __acquire_grant_for_copy(dd, op->dest.u.ref, 0, &d_frame,
+                                      &dest_off, &dest_len);
         if ( rc != GNTST_okay )
             goto error_out;
         have_d_grant = 1;
+        if ( op->dest.offset < dest_off ||
+             op->len > dest_len )
+            PIN_FAIL(error_out, GNTST_general_error,
+                     "copy dest out of bounds: %d < %d || %d > %d\n",
+                     op->dest.offset, dest_off,
+                     op->len, dest_len);
     }
     else
     {
diff -r 842baf721920 -r e9b623fd710f xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/public/grant_table.h  Mon Sep 22 13:09:07 2008 +0100
@@ -130,6 +130,9 @@
  *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
  *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
  *  GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]
+ *  GTF_sub_page: Grant access to only a subrange of the page.  @domid
+ *                will only be allowed to copy from the grant, and not
+ *                map it. [GST]
  */
 #define _GTF_readonly       (2)
 #define GTF_readonly        (1U<<_GTF_readonly)
@@ -143,6 +146,8 @@
 #define GTF_PCD             (1U<<_GTF_PCD)
 #define _GTF_PAT            (7)
 #define GTF_PAT             (1U<<_GTF_PAT)
+#define _GTF_sub_page       (8)
+#define GTF_sub_page        (1U<<_GTF_sub_page)
 
 /*
  * Subflags for GTF_accept_transfer:
@@ -200,6 +205,18 @@
         uint32_t pad0;
         uint64_t frame;
     } full_page;
+
+    /*
+     * If the grant type is GTF_grant_access and GTF_sub_page is set,
+     * @domid is allowed to access bytes [@page_off,@page_off+@length)
+     * in frame @frame.
+     */
+    struct {
+        grant_entry_header_t hdr;
+        uint16_t page_off;
+        uint16_t length;
+        uint64_t frame;
+    } sub_page;
 
     uint32_t __spacer[4]; /* Pad to a power of two */
 };
diff -r 842baf721920 -r e9b623fd710f xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h     Mon Sep 22 12:23:28 2008 +0100
+++ b/xen/include/xen/grant_table.h     Mon Sep 22 13:09:07 2008 +0100
@@ -30,10 +30,15 @@
 
 /* Active grant entry - used for shadowing GTF_permit_access grants. */
 struct active_grant_entry {
-    u32           pin;    /* Reference count information.  */
-    domid_t       domid;  /* Domain being granted access.  */
+    u32           pin;    /* Reference count information.             */
+    domid_t       domid;  /* Domain being granted access.             */
+    unsigned long frame;  /* Frame being granted.                     */
     unsigned long gfn;    /* Guest's idea of the frame being granted. */
-    unsigned long frame;  /* Frame being granted.          */
+    unsigned      is_sub_page:1; /* True if this is a sub-page grant. */
+    unsigned      start:15; /* For sub-page grants, the start offset
+                               in the page.                           */
+    unsigned      length:16; /* For sub-page grants, the length of the
+                                grant.                                */
 };
 
  /* Count of writable host-CPU mappings. */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel