[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH] 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> --- tools/libxc/xc_domain.c | 14 ++++++++++++ tools/libxc/xenctrl.h | 2 ++ tools/libxl/libxl_arm.c | 50 +++++++++++++++++++++++++++++++++++------ tools/libxl/libxl_types.idl | 1 + tools/libxl/xl_cmdimpl.c | 3 +++ xen/arch/arm/domctl.c | 21 ++++++++++++++++- xen/arch/arm/gic-v3.c | 13 ++++++++--- xen/include/public/arch-arm.h | 8 +++++++ xen/include/public/domctl.h | 10 +++++++++ 9 files changed, 111 insertions(+), 11 deletions(-) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 91d856e..69336e6 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -58,6 +58,20 @@ int xc_domain_configure(xc_interface *xch, uint32_t domid, domctl.u.configuredomain.nr_spis = nr_spis; return do_domctl(xch, &domctl); } + +int xc_domain_get_gicversion(xc_interface *xch, uint32_t domid, + uint32_t *version) +{ + int err; + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_get_gicversion; + domctl.domain = (domid_t)domid; + if ( (err = do_domctl(xch, &domctl)) != 0 ) + return err; + *version = domctl.u.getgicversion.version; + return 0; +} #endif int xc_domain_cacheflush(xc_interface *xch, uint32_t domid, diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 8234962..dfdbd3c 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -485,6 +485,8 @@ 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); +int xc_domain_get_gicversion(xc_interface *xch, uint32_t domid, + uint32_t *version); #endif /* Functions to produce a dump of a given domain diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c index 9605953..901032d 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; for (dev_index = 0; dev_index < d_config->num_dtdevs; dev_index++) nr_spis += state->dtdevs_info[dev_index].num_irqs; @@ -42,6 +43,16 @@ int libxl__arch_domain_create_pre(libxl__gc *gc, libxl_domain_config *d_config, return ERROR_FAIL; } + if (d_config->b_info.gic_version == 0) { + /* GIC version is not set. Query host */ + if (xc_domain_get_gicversion(CTX->xch, domid, &gic_version) != 0) { + LOG(ERROR, "Couldn't get GIC version from xen"); + return ERROR_FAIL; + } + d_config->b_info.gic_version = gic_version; + } + LOG(DEBUG, "GIC version %d\n", d_config->b_info.gic_version); + return 0; } @@ -384,7 +395,8 @@ static int make_memory_nodes(libxl__gc *gc, void *fdt, 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) + uint64_t gicc_base, uint64_t gicc_size, + int version) { int res; const char *name = GCSPRINTF("interrupt-controller@%"PRIx64, gicd_base); @@ -392,9 +404,13 @@ static int make_intc_node(libxl__gc *gc, void *fdt, 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,6 +423,16 @@ static int make_intc_node(libxl__gc *gc, void *fdt, res = fdt_property(fdt, "interrupt-controller", NULL, 0); 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, gicd_base, gicd_size, @@ -662,9 +688,19 @@ 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) ); + + if (info->gic_version == 3) { + FDT( make_intc_node(gc, fdt, + GUEST_GICV3_GICD_BASE, GUEST_GICV3_GICD_SIZE, + GUEST_GICV3_GICR_BASE, GUEST_GICV3_GICR_SIZE, + info->gic_version) ); + } + else { + FDT( make_intc_node(gc, fdt, + GUEST_GICD_BASE, GUEST_GICD_SIZE, + GUEST_GICC_BASE, GUEST_GICD_SIZE, + 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 e93dbfa..fde5361 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -340,6 +340,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 a32e754..ba3fb98 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1472,6 +1472,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..04f84ac 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, @@ -41,7 +43,24 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d, return domain_configure_vgic(d, domctl->u.configuredomain.nr_spis); } - + case XEN_DOMCTL_get_gicversion: + { + switch ( gic_hw_version() ) + { +#ifdef CONFIG_ARM_64 + case GIC_V3: + domctl->u.getgicversion.version = 3; + break; +#endif + case GIC_V2: + domctl->u.getgicversion.version = 2; + break; + default: + return -EINVAL; + } + return __copy_to_guest(u_domctl, domctl, 1); + } + 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 d3db078..b432ca4 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -372,6 +372,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 3d36128..9682ffd 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -76,6 +76,14 @@ struct xen_domctl_configuredomain { }; typedef struct xen_domctl_configuredomain xen_domctl_configuredomain_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_configuredomain_t); + +/* XEN_DOMCTL_get_gicversion */ +struct xen_domctl_getgicversion { + /* OUT parameters */ + uint32_t version; +}; +typedef struct xen_domctl_getgicversion xen_domctl_getgicversion_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_getgicversion_t); #endif /* XEN_DOMCTL_getdomaininfo */ @@ -1096,6 +1104,7 @@ struct xen_domctl { #define XEN_DOMCTL_configure_domain 75 #define XEN_DOMCTL_dtdev_op 76 #define XEN_DOMCTL_assign_dt_device 77 +#define XEN_DOMCTL_get_gicversion 78 #define XEN_DOMCTL_gdbsx_guestmemio 1000 #define XEN_DOMCTL_gdbsx_pausevcpu 1001 #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 @@ -1106,6 +1115,7 @@ struct xen_domctl { struct xen_domctl_createdomain createdomain; #if defined(__arm__) || defined(__aarch64__) struct xen_domctl_configuredomain configuredomain; + struct xen_domctl_getgicversion getgicversion; #endif struct xen_domctl_getdomaininfo getdomaininfo; struct xen_domctl_getmemlist getmemlist; -- 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 |