By default all guests are permitted to have up to 1024 maptrack frames,
which on 64-bit means an 8k frame table. Yet except for driver domains
guests normally don't make use of grant mappings. Defer allocating the
table until a map track handle is first requested.

Signed-off-by: Jan Beulich <[email protected]>
---
I continue to be unconvinced that it is a good idea to allow all DomU-s
1024 maptrack frames by default. While I'm still of the opinion that a
hypervisor enforced upper bound is okay, I question this upper bound
also getting used as the default value - this is perhaps okay for Dom0,
but not elsewhere.

--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -633,6 +633,34 @@ get_maptrack_handle(
     if ( likely(handle != INVALID_MAPTRACK_HANDLE) )
         return handle;
 
+    if ( unlikely(!read_atomic(&lgt->maptrack)) )
+    {
+        struct grant_mapping **maptrack = NULL;
+
+        if ( lgt->max_maptrack_frames )
+            maptrack = vzalloc(lgt->max_maptrack_frames * sizeof(*maptrack));
+
+        spin_lock(&lgt->maptrack_lock);
+
+        if ( !lgt->maptrack )
+        {
+            if ( !maptrack )
+            {
+                spin_unlock(&lgt->maptrack_lock);
+                return INVALID_MAPTRACK_HANDLE;
+            }
+
+            write_atomic(&lgt->maptrack, maptrack);
+            maptrack = NULL;
+
+            radix_tree_init(&lgt->maptrack_tree);
+        }
+
+        spin_unlock(&lgt->maptrack_lock);
+
+        vfree(maptrack);
+    }
+
     spin_lock(&lgt->maptrack_lock);
 
     /*
@@ -1955,16 +1983,6 @@ int grant_table_init(struct domain *d, i
     if ( gt->active == NULL )
         goto out;
 
-    /* Tracking of mapped foreign frames table */
-    if ( gt->max_maptrack_frames )
-    {
-        gt->maptrack = vzalloc(gt->max_maptrack_frames * 
sizeof(*gt->maptrack));
-        if ( gt->maptrack == NULL )
-            goto out;
-
-        radix_tree_init(&gt->maptrack_tree);
-    }
-
     /* Shared grant table. */
     gt->shared_raw = xzalloc_array(void *, gt->max_grant_frames);
     if ( gt->shared_raw == NULL )


Reply via email to