xen/arm: Find automatically the gnttab region for DOM0
authorJulien Grall <julien.grall@citrix.com>
Wed, 17 Jun 2015 13:58:27 +0000 (14:58 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 3 Jul 2015 09:02:04 +0000 (10:02 +0100)
Currently, the grant table region is hardcoded per-platform. When a new
board is coming up, we have to check the spec in order to find a space
in the memory layout free. Depending on the platform it may be tedious.

A good candidate for the gnttab region is the one used by Xen binary as
some part will never be mapped to the DOM0 address, MMIO are mapped 1:1
and the RAM will be either:
    - direct mapped: 1:1 mapping is used => no problem
    - non direct mapped: Xen always relocates himself as high as possible
    (limited to 4GB on ARM32) and the RAM bank are filled from the first
    one. It's very unlikely that the gnttab region will overlap with the
    RAM. Although for safety a check may be necessary when we will reenable
    the option.

Furthermore, there is plenty of space to contain a big gnttab, the default
size is 32 frame (i.e 128KB) but it can be changed via a command option.

It's not possible to use the whole region used by Xen, as some part of
the binary will be freed after Xen boot and can be used by DOM0 and other
guest. A sensible choice is the text secion as it will always reside in
memory never be mapped to the guest and the size is big enough (~300KB
on ARM64). It could be extended later to use other contiguous sections
such as data...

Note that on ARM64, the grant table region may be after 4GB (Xen is
relocated to the highest address) using DOM0 32 bit with short page table
may not work. Although, I don't think this is a big deal as device may not
work and/or the RAM is too high due to the 1:1 mapping.

This patch also drop the platforms thunderx and xilinx-zynqmp which became
dummy by dropping the hardcoding DOM0 grant table region.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
14 files changed:
xen/arch/arm/domain_build.c
xen/arch/arm/kernel.h
xen/arch/arm/platform.c
xen/arch/arm/platforms/Makefile
xen/arch/arm/platforms/midway.c
xen/arch/arm/platforms/omap5.c
xen/arch/arm/platforms/rcar2.c
xen/arch/arm/platforms/seattle.c
xen/arch/arm/platforms/sunxi.c
xen/arch/arm/platforms/thunderx.c [deleted file]
xen/arch/arm/platforms/vexpress.c
xen/arch/arm/platforms/xgene-storm.c
xen/arch/arm/platforms/xilinx-zynqmp.c [deleted file]
xen/include/asm-arm/platform.h

index e9cb8a9fdb5112130ae6c5b11543acb8f81e7dae..d8b775f2633e2007c0036e84645acb942a2bb4ff 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <asm/gic.h>
 #include <xen/irq.h>
+#include <xen/grant_table.h>
 #include "kernel.h"
 
 static unsigned int __initdata opt_dom0_max_vcpus;
@@ -605,8 +606,8 @@ static int make_memory_node(const struct domain *d,
     return res;
 }
 
-static int make_hypervisor_node(struct domain *d,
-                                void *fdt, const struct dt_device_node *parent)
+static int make_hypervisor_node(const struct kernel_info *kinfo,
+                                const struct dt_device_node *parent)
 {
     const char compat[] =
         "xen,xen-"__stringify(XEN_VERSION)"."__stringify(XEN_SUBVERSION)"\0"
@@ -615,9 +616,10 @@ static int make_hypervisor_node(struct domain *d,
     gic_interrupt_t intr;
     __be32 *cells;
     int res;
+    /* Convenience alias */
     int addrcells = dt_n_addr_cells(parent);
     int sizecells = dt_n_size_cells(parent);
-    paddr_t gnttab_start, gnttab_size;
+    void *fdt = kinfo->fdt;
 
     DPRINT("Create hypervisor node\n");
 
@@ -639,12 +641,9 @@ static int make_hypervisor_node(struct domain *d,
     if ( res )
         return res;
 
-    platform_dom0_gnttab(&gnttab_start, &gnttab_size);
-    DPRINT("  Grant table range: %#"PRIpaddr"-%#"PRIpaddr"\n",
-           gnttab_start, gnttab_start + gnttab_size);
     /* reg 0 is grant table space */
     cells = &reg[0];
-    dt_set_range(&cells, parent, gnttab_start, gnttab_size);
+    dt_set_range(&cells, parent, kinfo->gnttab_start, kinfo->gnttab_size);
     res = fdt_property(fdt, "reg", reg,
                        dt_cells_to_size(addrcells + sizecells));
     if ( res )
@@ -1192,7 +1191,7 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
 
     if ( node == dt_host )
     {
-        res = make_hypervisor_node(d, kinfo->fdt, node);
+        res = make_hypervisor_node(kinfo, node);
         if ( res )
             return res;
 
@@ -1368,6 +1367,37 @@ static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo)
         panic("Cannot fix up \"interrupts\" property of the hypervisor node");
 }
 
+static void __init find_gnttab_region(struct domain *d,
+                                      struct kernel_info *kinfo)
+{
+    /*
+     * The region used by Xen on the memory will never be mapped in DOM0
+     * memory layout. Therefore it can be used for the grant table.
+     *
+     * Only use the text section as it's always present and will contain
+     * enough space for a large grant table
+     */
+    kinfo->gnttab_start = __pa(_stext);
+    kinfo->gnttab_size = (_etext - _stext) & PAGE_MASK;
+
+    /* Make sure the grant table will fit in the region */
+    if ( (kinfo->gnttab_size >> PAGE_SHIFT) < max_grant_frames )
+        panic("Cannot find a space for the grant table region\n");
+
+#ifdef CONFIG_ARM_32
+    /*
+     * The gnttab region must be under 4GB in order to work with DOM0
+     * using short page table.
+     * In practice it's always the case because Xen is always located
+     * below 4GB, but be safe.
+     */
+    BUG_ON((kinfo->gnttab_start + kinfo->gnttab_size) > GB(4));
+#endif
+
+    printk("Grant table range: %#"PRIpaddr"-%#"PRIpaddr"\n",
+           kinfo->gnttab_start, kinfo->gnttab_start + kinfo->gnttab_size);
+}
+
 int construct_dom0(struct domain *d)
 {
     struct kernel_info kinfo = {};
@@ -1405,6 +1435,7 @@ int construct_dom0(struct domain *d)
 #endif
 
     allocate_memory(d, &kinfo);
+    find_gnttab_region(d, &kinfo);
 
     rc = prepare_dtb(d, &kinfo);
     if ( rc < 0 )
index 0050dfb130a72c3b96fe7fba2aecef1956af7620..c1b07d4f7b82758f1e46ffe4af58beadca304579 100644 (file)
@@ -22,6 +22,10 @@ struct kernel_info {
     /* kernel entry point */
     paddr_t entry;
 
+    /* grant table region */
+    paddr_t gnttab_start;
+    paddr_t gnttab_size;
+
     /* boot blob load addresses */
     const struct bootmodule *kernel_bootmodule, *initrd_bootmodule;
     paddr_t dtb_paddr;
index 70c1388f9e3a7ba1d8ee4d450f8ee3947b004488..0af6d57bfe04e5319071b156060bd9eb98afcdd5 100644 (file)
@@ -147,20 +147,6 @@ bool_t platform_device_is_blacklisted(const struct dt_device_node *node)
     return (dt_match_node(blacklist, node) != NULL);
 }
 
-void platform_dom0_gnttab(paddr_t *start, paddr_t *size)
-{
-    if ( platform && platform->dom0_gnttab_size )
-    {
-        *start = platform->dom0_gnttab_start;
-        *size = platform->dom0_gnttab_size;
-    }
-    else
-    {
-        *start = 0xb0000000;
-        *size = 0x20000;
-    }
-}
-
 /*
  * Local variables:
  * mode: C
index e7f2a4331ce7de422146291cba1b470b977086f2..e173fec1d587edd0bbb97996a60270027022056b 100644 (file)
@@ -6,6 +6,4 @@ obj-$(CONFIG_ARM_32) += omap5.o
 obj-$(CONFIG_ARM_32) += sunxi.o
 obj-$(CONFIG_ARM_32) += rcar2.o
 obj-$(CONFIG_ARM_64) += seattle.o
-obj-$(CONFIG_ARM_64) += thunderx.o
 obj-$(CONFIG_ARM_64) += xgene-storm.o
-obj-$(CONFIG_ARM_64) += xilinx-zynqmp.o
index 42f76975fb38697a8e271dc5cedef803abf5d645..b221279ec7ad5327d6536de942585540568da0c4 100644 (file)
@@ -51,9 +51,6 @@ static const char * const midway_dt_compat[] __initconst =
 PLATFORM_START(midway, "CALXEDA MIDWAY")
     .compatible = midway_dt_compat,
     .reset = midway_reset,
-
-    .dom0_gnttab_start = 0xff800000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 /*
index e7bf30d7fdc387acaf403426d61427a965b407d2..a49ba62fa86abf755af7c8a00a7920789fc5b188 100644 (file)
@@ -161,9 +161,6 @@ PLATFORM_START(omap5, "TI OMAP5")
     .specific_mapping = omap5_specific_mapping,
     .smp_init = omap5_smp_init,
     .cpu_up = cpu_up_send_sgi,
-
-    .dom0_gnttab_start = 0x4b000000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 PLATFORM_START(dra7, "TI DRA7")
@@ -171,9 +168,6 @@ PLATFORM_START(dra7, "TI DRA7")
     .init_time = omap5_init_time,
     .cpu_up = cpu_up_send_sgi,
     .smp_init = omap5_smp_init,
-
-    .dom0_gnttab_start = 0x4b000000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 /*
index aef544c248bb01b7e4daad961c4cb23ee7552604..bb25751109354b4b5e3d383c37c064df79580f88 100644 (file)
@@ -56,9 +56,6 @@ PLATFORM_START(rcar2, "Renesas R-Car Gen2")
     .compatible = rcar2_dt_compat,
     .cpu_up = cpu_up_send_sgi,
     .smp_init = rcar2_smp_init,
-
-    .dom0_gnttab_start = 0xc0000000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 /*
index 6cc53625ae357af3d3eb7709aa2da04288d65bb1..86dce911f7b2f24256f4043cc4d4a8f911b3338f 100644 (file)
@@ -45,9 +45,6 @@ PLATFORM_START(seattle, "SEATTLE")
     .compatible = seattle_dt_compat,
     .reset      = seattle_system_reset,
     .poweroff   = seattle_system_off,
-
-    .dom0_gnttab_start = 0xe1700000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 /*
index 89d8290c5eedce827927b260ea2ccc9d94f06644..0ba7b3d9b476a95edb653e120b7b3900a47f7c06 100644 (file)
@@ -69,9 +69,6 @@ PLATFORM_START(sunxi, "Allwinner A20")
     .compatible = sunxi_dt_compat,
     .blacklist_dev = sunxi_blacklist_dev,
     .reset = sunxi_reset,
-
-    .dom0_gnttab_start = 0x01d00000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 /*
diff --git a/xen/arch/arm/platforms/thunderx.c b/xen/arch/arm/platforms/thunderx.c
deleted file mode 100644 (file)
index be6f24f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * xen/arch/arm/platforms/thunderx.c
- *
- * Cavium Thunder specific settings
- *
- * Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
- * Copyright (c) 2015 Cavium Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <asm/platform.h>
-
-static const char * const thunderx_dt_compat[] __initconst =
-{
-    "cavium,thunder-88xx",
-    NULL
-};
-
-PLATFORM_START(thunderx, "THUNDERX")
-    .compatible = thunderx_dt_compat,
-    .dom0_gnttab_start = 0x40000000000,
-    .dom0_gnttab_size = 0x20000,
-PLATFORM_END
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- */
index ce66935f9ebd8b3e975cda23d31961b0108876bc..8e6a4eaa32e4267529ac370eee0e76994c81e515 100644 (file)
@@ -176,8 +176,6 @@ PLATFORM_START(vexpress, "VERSATILE EXPRESS")
 #endif
     .reset = vexpress_reset,
     .blacklist_dev = vexpress_blacklist_dev,
-    .dom0_gnttab_start = 0x10000000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 /*
index 1362beafe1656d5719b72dd50c57c284d6c5f03b..26754b5bd84d819c4bc2aab8728c81a80a690565 100644 (file)
@@ -266,9 +266,6 @@ PLATFORM_START(xgene_storm, "APM X-GENE STORM")
     .reset = xgene_storm_reset,
     .quirks = xgene_storm_quirks,
     .specific_mapping = xgene_storm_specific_mapping,
-
-    .dom0_gnttab_start = 0x1f800000,
-    .dom0_gnttab_size = 0x20000,
 PLATFORM_END
 
 /*
diff --git a/xen/arch/arm/platforms/xilinx-zynqmp.c b/xen/arch/arm/platforms/xilinx-zynqmp.c
deleted file mode 100644 (file)
index d03fb36..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * xen/arch/arm/platforms/xilinx-zynqmp.c
- *
- * Xilinx ZynqMP setup
- *
- * Copyright (c) 2015 Xilinx Inc.
- * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <asm/platform.h>
-
-static const char * const zynqmp_dt_compat[] __initconst =
-{
-    "xlnx,zynqmp",
-    NULL
-};
-
-PLATFORM_START(xgene_storm, "Xilinx ZynqMP")
-    .compatible = zynqmp_dt_compat,
-    .dom0_gnttab_start = 0xf0000000,
-    .dom0_gnttab_size = 0x20000,
-PLATFORM_END
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- */
index 283b50f3c58c06344c6a45c4ac9c4869116da02d..b8fc5aca015d8b7636aae901c5df869442d48ce1 100644 (file)
@@ -37,12 +37,6 @@ struct platform_desc {
      * List of devices which must not pass-through to a guest
      */
     const struct dt_device_match *blacklist_dev;
-    /*
-     * The location of a region of physical address space which dom0
-     * can use for grant table mappings. If size is zero defaults to
-     * 0xb0000000-0xb0020000.
-     */
-    paddr_t dom0_gnttab_start, dom0_gnttab_size;
 };
 
 /*
@@ -63,7 +57,6 @@ void platform_poweroff(void);
 bool_t platform_has_quirk(uint32_t quirk);
 bool_t platform_device_is_blacklisted(const struct dt_device_node *node);
 unsigned int platform_dom0_evtchn_ppi(void);
-void platform_dom0_gnttab(paddr_t *start, paddr_t *size);
 
 #define PLATFORM_START(_name, _namestr)                         \
 static const struct platform_desc  __plat_desc_##_name __used   \