xen/arm: Find automatically the gnttab region for DOM0

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>
This commit is contained in:
Julien Grall authored and Ian Campbell committed 2015-07-03 10:02:04 +01:00
1 parent 1123da20d3
commit 7e02c88160
14 files changed
+43 -136

No files matched your search

+39 -8
View 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 )
+4
View 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;
-14
View 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
-2
View 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
-3
View 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
/*
-6
View 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
/*
-3
View 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
/*
-3
View 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
/*
-3
View 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
/*
-41
View File
@@ -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:
*/
-2
View 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
/*
-3
View 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
/*
-41
View File
@@ -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:
*/
-7
View 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 \
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.