]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
xen/arm: don't initialize dom0 colors multiple times
authorStefano Stabellini <sstabellini@kernel.org>
Mon, 9 Dec 2019 22:50:28 +0000 (14:50 -0800)
committerLuca Miccio <206497@studenti.unimore.it>
Mon, 6 Jan 2020 14:07:35 +0000 (15:07 +0100)
Dom0less VMs get they colors array initialized twice: first in
arch_domain_create, then again in construct_domU. Also, not all VMs get
their color array printed properly on boot or checked for errors.

This patch fixes these issues by initializing dom0less VMs colors from
arch_domain_create, same as all other VMs. To do that, we need to
prepopulate the xen_domctl_createdomain struct with coloring
information. We also need special casing dom0less VMs in
arch_domain_create because otherwise copy_from_guest doesn't work for
Xen allocated memory.

Then, we check for errors and print the array of colors for each VM
(dom0, dom0less VMs, regular VMs) directly from arch_domain_create.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
xen/arch/arm/domain.c
xen/arch/arm/domain_build.c

index f89cab93ab954745a9fd1e48af2f7d301778839a..86d2a859d13088f243eaff3d1c09243235e3d262 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/procinfo.h>
 #include <asm/regs.h>
 #include <asm/tee/tee.h>
+#include <asm/setup.h>
 #include <asm/vfp.h>
 #include <asm/vgic.h>
 #include <asm/vtimer.h>
@@ -775,21 +776,31 @@ int arch_domain_create(struct domain *d,
         }
 
         d->max_colors = config->arch.colors.max_colors;
-        if ( copy_from_guest(d->colors, config->arch.colors.colors,
-                             d->max_colors) )
+        if ( d->domain_id <= max_init_domid )
+            memcpy(d->colors, config->arch.colors.colors.p, d->max_colors * sizeof(uint32_t));
+        else
         {
-            rc = -EINVAL;
-            printk(XENLOG_ERR "Failed to copy colors for dom%u\n", d->domain_id);
-            goto fail;
+            rc = copy_from_guest(d->colors, config->arch.colors.colors, d->max_colors);
+            if ( rc != 0 )
+            {
+                rc = -EINVAL;
+                printk(XENLOG_ERR "Failed to copy colors for dom%u\n", d->domain_id);
+                goto fail;
+            }
         }
+    }
 
-        if ( !check_domain_colors(d) )
-        {
-            rc = -EINVAL;
-            printk(XENLOG_ERR "Failed to check colors for dom%u\n", d->domain_id);
-            goto fail;
-        }
+    if ( !check_domain_colors(d) )
+    {
+        rc = -EINVAL;
+        printk(XENLOG_ERR "Failed to check colors for dom%u\n", d->domain_id);
+        goto fail;
     }
+
+    printk("Dom%u colors: [ ", d->domain_id);
+    for ( int i = 0; i < d->max_colors; i++ )
+        printk("%u ", d->colors[i]);
+    printk("]\n");
 #endif
     return 0;
 
index 8dcc4bf373f5a8457ab008a25051e87845015ab6..4d994f3bba5b707a9254d538cc8202ba1c07502f 100644 (file)
@@ -2396,9 +2396,8 @@ static int __init construct_domU(struct domain *d,
                                  const struct dt_device_node *node)
 {
     struct kernel_info kinfo = {};
-    int rc, i, k;
+    int rc;
     u64 mem;
-    u64 col_val;
 
     rc = dt_property_read_u64(node, "memory", &mem);
     if ( !rc )
@@ -2416,31 +2415,6 @@ static int __init construct_domU(struct domain *d,
         return -ENOMEM;
     d->max_pages = ~0U;
 
-    rc = dt_property_read_u64(node, "colors", &col_val);
-
-    if ( get_max_colors() && col_val )
-    {
-        printk("Colored configuration: 0x%"PRIx64"\n", col_val);
-        d->max_colors = 0;
-        if ( d->colors )
-            xfree(d->colors);
-
-        /* Calculate number of bit set */
-        for ( i = 0; i < get_max_colors(); i++)
-            if ( col_val & (1 << i) )
-                d->max_colors++;
-
-        d->colors = xzalloc_array(uint32_t, d->max_colors);
-        for ( i = 0, k = 0; k < d->max_colors; i++ )
-            if ( col_val & (1 << i) )
-                d->colors[k++] = i;
-
-        printk("DomU config: [ ");
-        for ( k = 0; k < d->max_colors; k++ )
-            printk("%u ", d->colors[k]);
-        printk("]\n");
-    }
-
     kinfo.d = d;
 
     rc = kernel_probe(&kinfo, node);
@@ -2471,6 +2445,8 @@ void __init create_domUs(void)
 {
     struct dt_device_node *node;
     const struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
+    u64 col_val = 0;
+    uint32_t *colors = NULL;
 
     BUG_ON(chosen == NULL);
     dt_for_each_child_node(chosen, node)
@@ -2507,7 +2483,30 @@ void __init create_domUs(void)
                                          GUEST_VPL011_SPI - 32 + 1);
         }
 
+        d_cfg.arch.colors.max_colors = 0;
+        dt_property_read_u64(node, "colors", &col_val);
+        if ( get_max_colors() && col_val )
+        {
+            int i, k;
+
+            printk("Colored configuration: 0x%"PRIx64"\n", col_val);
+
+            /* Calculate number of bit set */
+            for ( i = 0; i < get_max_colors(); i++)
+                if ( col_val & (1 << i) )
+                    d_cfg.arch.colors.max_colors++;
+
+            colors = xzalloc_array(uint32_t, d_cfg.arch.colors.max_colors);
+            if ( !colors )
+                panic("Cannot allocate memory");
+            for ( i = 0, k = 0; k < d_cfg.arch.colors.max_colors; i++ )
+                if ( col_val & (1 << i) )
+                    colors[k++] = i;
+            set_xen_guest_handle(d_cfg.arch.colors.colors, colors);
+        }
+
         d = domain_create(++max_init_domid, &d_cfg, false);
+
         if ( IS_ERR(d) )
             panic("Error creating domain %s\n", dt_node_name(node));
 
@@ -2517,6 +2516,7 @@ void __init create_domUs(void)
             panic("Could not set up domain %s\n", dt_node_name(node));
 
         domain_unpause_by_systemcontroller(d);
+        xfree(colors);
     }
 }