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

[Xen-changelog] [xen-unstable] xen: Preserve reserved grant entries when switching versions



# HG changeset patch
# User Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
# Date 1327758581 0
# Node ID 39df93acd4089eaae138e1decf49aec39fb19417
# Parent  926e0820d615d7224f22a44deb8bbf4ebf078cf0
xen: Preserve reserved grant entries when switching versions

In order for the toolstack to use reserved grant table entries, the
grant table for a guest must be initialized prior to the guest's boot.
When the guest switches grant table versions (necessary if the guest
is using v2 grant tables, or on kexec if switching grant versions),
these initial grants will be cleared. Instead of clearing them,
preserve the grants across the type change.

Attempting to preserve v2-only features such as sub-page grants will
produce a warning and clear the resulting v1 grant entry.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Committed-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 926e0820d615 -r 39df93acd408 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Sat Jan 28 13:49:05 2012 +0000
+++ b/xen/common/grant_table.c  Sat Jan 28 13:49:41 2012 +0000
@@ -2111,6 +2111,7 @@
     struct domain *d = current->domain;
     struct grant_table *gt = d->grant_table;
     struct active_grant_entry *act;
+    grant_entry_v1_t reserved_entries[GNTTAB_NR_RESERVED_ENTRIES];
     long res;
     int i;
 
@@ -2127,11 +2128,12 @@
 
     spin_lock(&gt->lock);
     /* Make sure that the grant table isn't currently in use when we
-       change the version number. */
-    /* (You need to change the version number for e.g. kexec.) */
+       change the version number, except for the first 8 entries which
+       are allowed to be in use (xenstore/xenconsole keeps them mapped).
+       (You need to change the version number for e.g. kexec.) */
     if ( gt->gt_version != 0 )
     {
-        for ( i = 0; i < nr_grant_entries(gt); i++ )
+        for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ )
         {
             act = &active_entry(gt, i);
             if ( act->pin != 0 )
@@ -2156,15 +2158,55 @@
             goto out_unlock;
     }
 
+    /* Preserve the first 8 entries (toolstack reserved grants) */
+    if ( gt->gt_version == 1 )
+    {
+        memcpy(reserved_entries, &shared_entry_v1(gt, 0), 
sizeof(reserved_entries));
+    }
+    else if ( gt->gt_version == 2 )
+    {
+        for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES && i < 
nr_grant_entries(gt); i++ )
+        {
+            int flags = status_entry(gt, i);
+            flags |= shared_entry_v2(gt, i).hdr.flags;
+            if ((flags & GTF_type_mask) == GTF_permit_access)
+            {
+                reserved_entries[i].flags = flags;
+                reserved_entries[i].domid = shared_entry_v2(gt, i).hdr.domid;
+                reserved_entries[i].frame = shared_entry_v2(gt, 
i).full_page.frame;
+            }
+            else
+            {
+                if ((flags & GTF_type_mask) != GTF_invalid)
+                    gdprintk(XENLOG_INFO, "d%d: bad flags %x in grant %d when 
switching grant version\n",
+                           d->domain_id, flags, i);
+                memset(&reserved_entries[i], 0, sizeof(reserved_entries[i]));
+            }
+        }
+    }
+
     if ( op.version < 2 && gt->gt_version == 2 )
         gnttab_unpopulate_status_frames(d, gt);
 
-    if ( op.version != gt->gt_version )
+    /* Make sure there's no crud left over in the table from the
+       old version. */
+    for ( i = 0; i < nr_grant_frames(gt); i++ )
+        memset(gt->shared_raw[i], 0, PAGE_SIZE);
+
+    /* Restore the first 8 entries (toolstack reserved grants) */
+    if ( gt->gt_version != 0 && op.version == 1 )
     {
-        /* Make sure there's no crud left over in the table from the
-           old version. */
-        for ( i = 0; i < nr_grant_frames(gt); i++ )
-            memset(gt->shared_raw[i], 0, PAGE_SIZE);
+        memcpy(&shared_entry_v1(gt, 0), reserved_entries, 
sizeof(reserved_entries));
+    }
+    else if ( gt->gt_version != 0 && op.version == 2 )
+    {
+        for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ )
+        {
+            status_entry(gt, i) = reserved_entries[i].flags & 
(GTF_reading|GTF_writing);
+            shared_entry_v2(gt, i).hdr.flags = reserved_entries[i].flags & 
~(GTF_reading|GTF_writing);
+            shared_entry_v2(gt, i).hdr.domid = reserved_entries[i].domid;
+            shared_entry_v2(gt, i).full_page.frame = reserved_entries[i].frame;
+        }
     }
 
     gt->gt_version = op.version;
diff -r 926e0820d615 -r 39df93acd408 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Sat Jan 28 13:49:05 2012 +0000
+++ b/xen/include/public/grant_table.h  Sat Jan 28 13:49:41 2012 +0000
@@ -117,6 +117,13 @@
 };
 typedef struct grant_entry_v1 grant_entry_v1_t;
 
+/* The first few grant table entries will be preserved across grant table
+ * version changes and may be pre-populated at domain creation by tools.
+ */
+#define GNTTAB_NR_RESERVED_ENTRIES     8
+#define GNTTAB_RESERVED_CONSOLE        0
+#define GNTTAB_RESERVED_XENSTORE       1
+
 /*
  * Type of grant entry.
  *  GTF_invalid: This grant entry grants no privileges.

_______________________________________________
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®.