[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH v2] xen/arm: Add support for GICv3 for domU
From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> With this patch gic version can be specified in cfg file. If no gic version is specified, xl tool queries host supported gic version and generate gic dt node accordingly. Ex: If gic_version is 3, gic dt node for GICv3 is generated. Specify gic version in cfg as 'gic_version = <version>' This patch is based on Julien's non-pci passthrough patch series. Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> --- v2: - Used domainconfigure domctl to fetch gic version - domainconfigure return error if gic version is not compatible - Remove register data parameters in make_intc_node() and add pass gic version as parameter --- tools/libxc/include/xenctrl.h | 2 +- tools/libxc/xc_domain.c | 10 +++++-- tools/libxl/libxl_arm.c | 60 ++++++++++++++++++++++++++++++----------- tools/libxl/libxl_types.idl | 1 + tools/libxl/xl_cmdimpl.c | 3 +++ xen/arch/arm/domctl.c | 33 +++++++++++++++++++++-- xen/arch/arm/gic-v3.c | 13 ++++++--- xen/include/public/arch-arm.h | 8 ++++++ xen/include/public/domctl.h | 2 ++ 9 files changed, 108 insertions(+), 24 deletions(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 51cba70..56fe74c 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -484,7 +484,7 @@ int xc_domain_create(xc_interface *xch, #if defined(__arm__) || defined(__aarch64__) int xc_domain_configure(xc_interface *xch, uint32_t domid, - uint32_t nr_spis); + uint32_t nr_spis, uint32_t *gic_version); #endif /* Functions to produce a dump of a given domain diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index a55b5a8..b96c178 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -50,13 +50,19 @@ int xc_domain_create(xc_interface *xch, #if defined(__arm__) || defined(__arch64__) int xc_domain_configure(xc_interface *xch, uint32_t domid, - uint32_t nr_spis) + uint32_t nr_spis, uint32_t *version) { + int err; DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_configure_domain; domctl.domain = (domid_t)domid; domctl.u.configuredomain.nr_spis = nr_spis; - return do_domctl(xch, &domctl); + domctl.u.configuredomain.gic_version = *version; + if ( (err = do_domctl(xch, &domctl)) != 0 ) + return err; + *version = domctl.u.configuredomain.gic_version; + return 0; } #endif diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c index 9605953..8475d1e 100644 --- a/tools/libxl/libxl_arm.c +++ b/tools/libxl/libxl_arm.c @@ -29,6 +29,7 @@ int libxl__arch_domain_create_pre(libxl__gc *gc, libxl_domain_config *d_config, { int dev_index; uint32_t nr_spis = 0; + uint32_t gic_version = d_config->b_info.gic_version; for (dev_index = 0; dev_index < d_config->num_dtdevs; dev_index++) nr_spis += state->dtdevs_info[dev_index].num_irqs; @@ -37,10 +38,14 @@ int libxl__arch_domain_create_pre(libxl__gc *gc, libxl_domain_config *d_config, LOG(DEBUG, "Allocate %u SPIs\n", nr_spis); - if (xc_domain_configure(CTX->xch, domid, nr_spis) != 0) { + if (xc_domain_configure(CTX->xch, domid, nr_spis, &gic_version) != 0) { LOG(ERROR, "Couldn't configure the domain"); return ERROR_FAIL; } + LOG(DEBUG, "Specified GIC version %d GIC version supported %d\n", + d_config->b_info.gic_version, gic_version); + + d_config->b_info.gic_version = gic_version; return 0; } @@ -382,19 +387,26 @@ static int make_memory_nodes(libxl__gc *gc, void *fdt, return 0; } -static int make_intc_node(libxl__gc *gc, void *fdt, - uint64_t gicd_base, uint64_t gicd_size, - uint64_t gicc_base, uint64_t gicc_size) +static int make_intc_node(libxl__gc *gc, void *fdt, int version) { int res; - const char *name = GCSPRINTF("interrupt-controller@%"PRIx64, gicd_base); + const char *name; + + if (version == 3) + name = GCSPRINTF("interrupt-controller@%"PRIx64, (uint64_t)GUEST_GICV3_GICD_BASE); + else + name = GCSPRINTF("interrupt-controller@%"PRIx64, (uint64_t)GUEST_GICD_BASE); res = fdt_begin_node(fdt, name); if (res) return res; - res = fdt_property_compat(gc, fdt, 2, - "arm,cortex-a15-gic", - "arm,cortex-a9-gic"); + if (version == 3) + res = fdt_property_compat(gc, fdt, 1, + "arm,gic-v3"); + else + res = fdt_property_compat(gc, fdt, 2, + "arm,cortex-a15-gic", + "arm,cortex-a9-gic"); if (res) return res; @@ -407,11 +419,29 @@ static int make_intc_node(libxl__gc *gc, void *fdt, res = fdt_property(fdt, "interrupt-controller", NULL, 0); if (res) return res; - res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS, - 2, - gicd_base, gicd_size, - gicc_base, gicc_size); - if (res) return res; + if (version == 3) { + res = fdt_property_cell(fdt, "redistributor-stride", + GUEST_GICV3_RDIST_STRIDE); + if (res) return res; + + res = fdt_property_cell(fdt, "#redistributor-regions", + GUEST_GICV3_RDIST_REGIONS); + if (res) return res; + + res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS, + 2, + GUEST_GICV3_GICD_BASE, GUEST_GICV3_GICD_SIZE, + GUEST_GICV3_GICR_BASE, GUEST_GICV3_GICR_SIZE); + if (res) return res; + } + else + { + res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS, + 2, + GUEST_GICD_BASE, GUEST_GICD_SIZE, + GUEST_GICC_BASE, GUEST_GICD_SIZE); + if (res) return res; + } res = fdt_property_cell(fdt, "linux,phandle", PHANDLE_GIC); if (res) return res; @@ -662,10 +692,8 @@ next_resize: FDT( make_psci_node(gc, fdt) ); FDT( make_memory_nodes(gc, fdt, dom) ); - FDT( make_intc_node(gc, fdt, - GUEST_GICD_BASE, GUEST_GICD_SIZE, - GUEST_GICC_BASE, GUEST_GICD_SIZE) ); + FDT( make_intc_node(gc, fdt, info->gic_version) ); FDT( make_timer_node(gc, fdt, ainfo) ); FDT( make_hypervisor_node(gc, fdt, vers) ); diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 7d9eec2..8f3f074 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -349,6 +349,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("disable_migrate", libxl_defbool), ("cpuid", libxl_cpuid_policy_list), ("blkdev_start", string), + ("gic_version", uint32), ("device_model_version", libxl_device_model_version), ("device_model_stubdomain", libxl_defbool), diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 2ec17ca..5fcb396 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1523,6 +1523,9 @@ skip_vfb: if (!xlu_cfg_get_long (config, "pci_seize", &l, 0)) pci_seize = l; + if (!xlu_cfg_get_long (config, "gic_version", &l, 0)) + b_info->gic_version = l; + /* To be reworked (automatically enabled) once the auto ballooning * after guest starts is done (with PCI devices passed in). */ if (c_info->type == LIBXL_DOMAIN_TYPE_PV) { diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c index 370dd99..1bea026 100644 --- a/xen/arch/arm/domctl.c +++ b/xen/arch/arm/domctl.c @@ -10,6 +10,8 @@ #include <xen/errno.h> #include <xen/sched.h> #include <xen/hypercall.h> +#include <asm/gic.h> +#include <xen/guest_access.h> #include <public/domctl.h> long arch_do_domctl(struct xen_domctl *domctl, struct domain *d, @@ -39,9 +41,36 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d, if ( domctl->u.configuredomain.nr_spis > (gic_number_lines() - 32) ) return -EINVAL; - return domain_configure_vgic(d, domctl->u.configuredomain.nr_spis); - } + if ( domain_configure_vgic(d, domctl->u.configuredomain.nr_spis) ) + return -EINVAL; + switch ( gic_hw_version() ) + { +#ifdef CONFIG_ARM_64 + case GIC_V3: + if ( domctl->u.configuredomain.gic_version == 0 ) + { + domctl->u.configuredomain.gic_version = 3; + return __copy_to_guest(u_domctl, domctl, 1); + } + /* XXX: Support only v3 gic emulation */ + if ( domctl->u.configuredomain.gic_version != 3 ) + return -EINVAL; + break; +#endif + case GIC_V2: + if ( domctl->u.configuredomain.gic_version == 0 ) + { + domctl->u.configuredomain.gic_version = 2; + return __copy_to_guest(u_domctl, domctl, 1); + } + if ( domctl->u.configuredomain.gic_version != 2 ) + return -EINVAL; + break; + default: + return -EINVAL; + } + } default: { int rc; diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index 9bdda32..059b60e 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -907,9 +907,16 @@ static int gicv_v3_init(struct domain *d) d->arch.vgic.rdist_count = gicv3.rdist_count; } else - d->arch.vgic.dbase = GUEST_GICD_BASE; + { + d->arch.vgic.dbase = GUEST_GICV3_GICD_BASE; + d->arch.vgic.dbase_size = GUEST_GICV3_GICD_SIZE; + + /* XXX: Only one Re-distributor region mapped for guest */ + d->arch.vgic.rdist_count = 1; + d->arch.vgic.rbase[0] = GUEST_GICV3_GICR_BASE; + d->arch.vgic.rbase_size[0] = GUEST_GICV3_GICR_SIZE; + d->arch.vgic.rdist_stride = GUEST_GICV3_RDIST_STRIDE; + } return 0; } diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index cebb349..6f80c99 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -363,6 +363,14 @@ typedef uint64_t xen_callback_t; * should instead use the FDT. */ +/* GICv3 address space */ +#define GUEST_GICV3_GICD_BASE 0x03001000ULL +#define GUEST_GICV3_GICD_SIZE 0x10000ULL +#define GUEST_GICV3_GICR_BASE 0x03020000ULL +#define GUEST_GICV3_GICR_SIZE 0x200000ULL +#define GUEST_GICV3_RDIST_STRIDE 0x20000ULL +#define GUEST_GICV3_RDIST_REGIONS 0x1ULL + /* Physical Address Space */ #define GUEST_GICD_BASE 0x03001000ULL #define GUEST_GICD_SIZE 0x00001000ULL diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 8adb8e2..502cfb6 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -73,6 +73,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t); struct xen_domctl_configuredomain { /* IN parameters */ uint32_t nr_spis; + /* IN/OUT parameter */ + uint32_t gic_version; }; typedef struct xen_domctl_configuredomain xen_domctl_configuredomain_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_configuredomain_t); -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |