[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 for 4.5] xen/arm: Add support for GICv3 for domU
On Mon, Nov 03, 2014 at 06:07:33PM +0530, Vijay Kilari wrote: > On Mon, Nov 3, 2014 at 4:31 PM, Stefano Stabellini > <stefano.stabellini@xxxxxxxxxxxxx> wrote: > > On Sat, 1 Nov 2014, Julien Grall wrote: > >> The vGIC will emulate the same version as the hardware. The toolstack has > >> to retrieve the version of the vGIC in order to be able to create the > >> corresponding device tree node. > >> > >> A new DOMCTL has been introduced for ARM to configure the domain. For now > >> it only allow the toolstack to retrieve the version of vGIC. > >> This DOMCTL will be extend later to let the user choose the version of the > >> emulated GIC. > >> > >> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> > >> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> > >> Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> > >> Cc: Jan Beulich <jbeulich@xxxxxxxx> > >> Cc: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx> > >> Cc: Wei Liu <wei.liu2@xxxxxxxxxx> > > > > Reviewed-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > > Tested with GICv3 platform. Thank you for doing that. It also needs Acks from Daniel and Jan. > > > > > > >> Changes in v2: > >> - Use memcpu in xc_domain_configure > >> - Rename the DOMCTL into domctl_arm_configuredomain > >> - Drop arch_domain_create_pre. Will be reintroduced in Xen 4.6 > >> and fold the code in arch_domain_init_hw_description > >> - Return -EOPNOTSUPP when the value of gic_version is not > >> supported > >> > >> This patch is based on Vijay's GICv3 guest support patch [1] and my patch > >> to > >> defer the initialization of the vGIC [2]. > >> > >> Xen 4.5 has already support for the hardware GICv3. While it's possible to > >> boot and use DOM0, there is no guest support. The first version of this > >> patch > >> has been sent a couple of months ago, but has never reached unstable for > >> various reasons (based on deferred series, lake of review at that time...). > >> Without it, platform with GICv3 support won't be able to boot any guest. > >> > >> The patch has been reworked to make it acceptable for Xen 4.5. Except the > >> new > >> DOMCTL to retrieve the GIC version and one check. The code is purely GICv3. > >> > >> Features such as adding a new config option to let the user choose the GIC > >> version are deferred to Xen 4.6. > >> > >> It has been tested on both GICv2/GICv3 platform. And build tested for x86. > >> > >> [1] http://lists.xen.org/archives/html/xen-devel/2014-10/msg00583.html > >> [2] https://patches.linaro.org/34664/ > >> --- > >> tools/flask/policy/policy/modules/xen/xen.if | 2 +- > >> tools/libxc/include/xenctrl.h | 6 ++ > >> tools/libxc/xc_domain.c | 20 ++++++ > >> tools/libxl/libxl_arm.c | 97 > >> ++++++++++++++++++++++++-- > >> xen/arch/arm/domctl.c | 35 ++++++++++ > >> xen/arch/arm/gic-v3.c | 16 ++++- > >> xen/include/public/arch-arm.h | 16 +++++ > >> xen/include/public/domctl.h | 17 +++++ > >> xen/xsm/flask/hooks.c | 3 + > >> xen/xsm/flask/policy/access_vectors | 2 + > >> 10 files changed, 206 insertions(+), 8 deletions(-) > >> > >> diff --git a/tools/flask/policy/policy/modules/xen/xen.if > >> b/tools/flask/policy/policy/modules/xen/xen.if > >> index 641c797..fa69c9d 100644 > >> --- a/tools/flask/policy/policy/modules/xen/xen.if > >> +++ b/tools/flask/policy/policy/modules/xen/xen.if > >> @@ -49,7 +49,7 @@ define(`create_domain_common', ` > >> getdomaininfo hypercall setvcpucontext > >> setextvcpucontext > >> getscheduler getvcpuinfo getvcpuextstate getaddrsize > >> getaffinity setaffinity }; > >> - allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim > >> set_max_evtchn set_vnumainfo get_vnumainfo psr_cmt_op }; > >> + allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim > >> set_max_evtchn set_vnumainfo get_vnumainfo psr_cmt_op configure_domain }; > >> allow $1 $2:security check_context; > >> allow $1 $2:shadow enable; > >> allow $1 $2:mmu { map_read map_write adjust memorymap physmap > >> pinpage mmuext_op }; > >> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h > >> index 564e187..45e282c 100644 > >> --- a/tools/libxc/include/xenctrl.h > >> +++ b/tools/libxc/include/xenctrl.h > >> @@ -483,6 +483,12 @@ int xc_domain_create(xc_interface *xch, > >> uint32_t flags, > >> uint32_t *pdomid); > >> > >> +#if defined(__arm__) || defined(__aarch64__) > >> +typedef xen_domctl_arm_configuredomain_t xc_domain_configuration_t; > >> + > >> +int xc_domain_configure(xc_interface *xch, uint32_t domid, > >> + xc_domain_configuration_t *config); > >> +#endif > >> > >> /* Functions to produce a dump of a given domain > >> * xc_domain_dumpcore - produces a dump to a specified file > >> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c > >> index a9bcd4a..1aa1f45 100644 > >> --- a/tools/libxc/xc_domain.c > >> +++ b/tools/libxc/xc_domain.c > >> @@ -48,6 +48,26 @@ int xc_domain_create(xc_interface *xch, > >> return 0; > >> } > >> > >> +#if defined(__arm__) || defined(__aarch64__) > >> +int xc_domain_configure(xc_interface *xch, uint32_t domid, > >> + xc_domain_configuration_t *config) > >> +{ > >> + int rc; > >> + DECLARE_DOMCTL; > >> + > >> + domctl.cmd = XEN_DOMCTL_arm_configure_domain; > >> + domctl.domain = (domid_t)domid; > >> + /* xc_domain_configure_t is an alias to > >> xen_domctl_arm_configuredomain */ > >> + memcpy(&domctl.u.configuredomain, config, sizeof(*config)); > >> + > >> + rc = do_domctl(xch, &domctl); > >> + if ( !rc ) > >> + memcpy(config, &domctl.u.configuredomain, sizeof(*config)); > >> + > >> + return rc; > >> +} > >> +#endif > >> + > >> int xc_domain_cacheflush(xc_interface *xch, uint32_t domid, > >> xen_pfn_t start_pfn, xen_pfn_t nr_pfns) > >> { > >> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c > >> index a122e4a..3dd6e7c 100644 > >> --- a/tools/libxl/libxl_arm.c > >> +++ b/tools/libxl/libxl_arm.c > >> @@ -23,6 +23,18 @@ > >> #define DT_IRQ_TYPE_LEVEL_HIGH 0x00000004 > >> #define DT_IRQ_TYPE_LEVEL_LOW 0x00000008 > >> > >> +static const char *gicv_to_string(uint8_t gic_version) > >> +{ > >> + switch (gic_version) { > >> + case XEN_DOMCTL_CONFIG_GIC_V2: > >> + return "V2"; > >> + case XEN_DOMCTL_CONFIG_GIC_V3: > >> + return "V3"; > >> + default: > >> + return "unknown"; > >> + } > >> +} > >> + > >> int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config > >> *d_config, > >> uint32_t domid) > >> { > >> @@ -307,9 +319,9 @@ 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_gicv2_node(libxl__gc *gc, void *fdt, > >> + uint64_t gicd_base, uint64_t gicd_size, > >> + uint64_t gicc_base, uint64_t gicc_size) > >> { > >> int res; > >> const char *name = GCSPRINTF("interrupt-controller@%"PRIx64, > >> gicd_base); > >> @@ -350,6 +362,57 @@ static int make_intc_node(libxl__gc *gc, void *fdt, > >> return 0; > >> } > >> > >> +static int make_gicv3_node(libxl__gc *gc, void *fdt) > >> +{ > >> + int res; > >> + const uint64_t gicd_base = GUEST_GICV3_GICD_BASE; > >> + const uint64_t gicd_size = GUEST_GICV3_GICD_SIZE; > >> + const uint64_t gicr0_base = GUEST_GICV3_GICR0_BASE; > >> + const uint64_t gicr0_size = GUEST_GICV3_GICR0_SIZE; > >> + const char *name = GCSPRINTF("interrupt-controller@%"PRIx64, > >> gicd_base); > >> + > >> + res = fdt_begin_node(fdt, name); > >> + if (res) return res; > >> + > >> + res = fdt_property_compat(gc, fdt, 1, > >> + "arm,gic-v3"); > >> + if (res) return res; > >> + > >> + res = fdt_property_cell(fdt, "#interrupt-cells", 3); > >> + if (res) return res; > >> + > >> + res = fdt_property_cell(fdt, "#address-cells", 0); > >> + if (res) return res; > >> + > >> + res = fdt_property(fdt, "interrupt-controller", NULL, 0); > >> + if (res) return res; > >> + > >> + 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, > >> + gicr0_base, gicr0_size); > >> + if (res) return res; > >> + > >> + res = fdt_property_cell(fdt, "linux,phandle", PHANDLE_GIC); > >> + if (res) return res; > >> + > >> + res = fdt_property_cell(fdt, "phandle", PHANDLE_GIC); > >> + if (res) return res; > >> + > >> + res = fdt_end_node(fdt); > >> + if (res) return res; > >> + > >> + return 0; > >> +} > >> + > >> static int make_timer_node(libxl__gc *gc, void *fdt, const struct > >> arch_info *ainfo) > >> { > >> int res; > >> @@ -456,6 +519,7 @@ int libxl__arch_domain_init_hw_description(libxl__gc > >> *gc, > >> libxl_domain_build_info *info, > >> struct xc_dom_image *dom) > >> { > >> + xc_domain_configuration_t config; > >> void *fdt = NULL; > >> int rc, res; > >> size_t fdt_size = 0; > >> @@ -471,8 +535,16 @@ int libxl__arch_domain_init_hw_description(libxl__gc > >> *gc, > >> ainfo = get_arch_info(gc, dom); > >> if (ainfo == NULL) return ERROR_FAIL; > >> > >> + LOG(DEBUG, "configure the domain"); > >> + config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT; > >> + if (xc_domain_configure(CTX->xch, dom->guest_domid, &config) != 0) { > >> + LOG(ERROR, "counldn't configure the domain"); > >> + return ERROR_FAIL; > >> + } > >> + > >> LOG(DEBUG, "constructing DTB for Xen version %d.%d guest", > >> vers->xen_version_major, vers->xen_version_minor); > >> + LOG(DEBUG, " - vGIC version: %s", > >> gicv_to_string(config.gic_version)); > >> > >> /* > >> * Call "call" handling FDR_ERR_*. Will either: > >> @@ -520,9 +592,22 @@ 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) ); > >> + > >> + switch (config.gic_version) { > >> + case XEN_DOMCTL_CONFIG_GIC_V2: > >> + FDT( make_gicv2_node(gc, fdt, > >> + GUEST_GICD_BASE, GUEST_GICD_SIZE, > >> + GUEST_GICC_BASE, GUEST_GICC_SIZE) ); > >> + break; > >> + case XEN_DOMCTL_CONFIG_GIC_V3: > >> + FDT( make_gicv3_node(gc, fdt) ); > >> + break; > >> + default: > >> + LOG(ERROR, "Unknown how to create the DT node for gic_version > >> = %d", > >> + config.gic_version); > >> + rc = ERROR_FAIL; > >> + goto out; > >> + } > >> > >> FDT( make_timer_node(gc, fdt, ainfo) ); > >> FDT( make_hypervisor_node(gc, fdt, vers) ); > >> diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c > >> index 45974e7..5b8ff57 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, > >> @@ -30,6 +32,39 @@ long arch_do_domctl(struct xen_domctl *domctl, struct > >> domain *d, > >> > >> return p2m_cache_flush(d, s, e); > >> } > >> + case XEN_DOMCTL_arm_configure_domain: > >> + { > >> + uint8_t gic_version; > >> + > >> + /* > >> + * Xen 4.5: The vGIC is emulating the same version of the > >> + * hardware GIC. Only the value XEN_DOMCTL_CONFIG_GIC_DEFAULT > >> + * is allowed. The DOMCTL will return the actual version of the > >> + * GIC. > >> + */ > >> + if ( domctl->u.configuredomain.gic_version != > >> XEN_DOMCTL_CONFIG_GIC_DEFAULT ) > >> + return -EOPNOTSUPP; > >> + > >> + switch ( gic_hw_version() ) > >> + { > >> + case GIC_V3: > >> + gic_version = XEN_DOMCTL_CONFIG_GIC_V3; > >> + break; > >> + case GIC_V2: > >> + gic_version = XEN_DOMCTL_CONFIG_GIC_V2; > >> + break; > >> + default: > >> + BUG(); > >> + } > >> + > >> + domctl->u.configuredomain.gic_version = gic_version; > >> + > >> + /* TODO: Make the copy generic for all ARCH domctl */ > >> + if ( __copy_to_guest(u_domctl, domctl, 1) ) > >> + return -EFAULT; > >> + > >> + return 0; > >> + } > >> > >> default: > >> return subarch_do_domctl(domctl, d, u_domctl); > >> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c > >> index 91161a2..076aa62 100644 > >> --- a/xen/arch/arm/gic-v3.c > >> +++ b/xen/arch/arm/gic-v3.c > >> @@ -906,7 +906,21 @@ 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 the guest */ > >> + BUILD_BUG_ON(GUEST_GICV3_RDIST_REGIONS != 1); > >> + > >> + d->arch.vgic.rdist_count = GUEST_GICV3_RDIST_REGIONS; > >> + d->arch.vgic.rdist_stride = GUEST_GICV3_RDIST_STRIDE; > >> + > >> + /* The first redistributor should contain enough space for all > >> CPUs */ > >> + BUILD_BUG_ON((GUEST_GICV3_GICR0_SIZE / GUEST_GICV3_RDIST_STRIDE) > >> < MAX_VIRT_CPUS); > >> + d->arch.vgic.rbase[0] = GUEST_GICV3_GICR0_BASE; > >> + d->arch.vgic.rbase_size[0] = GUEST_GICV3_GICR0_SIZE; > >> + } > >> > >> d->arch.vgic.nr_lines = 0; > >> > >> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h > >> index eecc561..d7df274 100644 > >> --- a/xen/include/public/arch-arm.h > >> +++ b/xen/include/public/arch-arm.h > >> @@ -373,11 +373,27 @@ typedef uint64_t xen_callback_t; > >> */ > >> > >> /* Physical Address Space */ > >> + > >> +/* vGIC mappings: Only one set of mapping is used by the guest. > >> + * Therefore they can overlap. > >> + */ > >> + > >> +/* vGIC v2 mappings */ > >> #define GUEST_GICD_BASE 0x03001000ULL > >> #define GUEST_GICD_SIZE 0x00001000ULL > >> #define GUEST_GICC_BASE 0x03002000ULL > >> #define GUEST_GICC_SIZE 0x00000100ULL > >> > >> +/* vGIC v3 mappings */ > >> +#define GUEST_GICV3_GICD_BASE 0x03001000ULL > >> +#define GUEST_GICV3_GICD_SIZE 0x00010000ULL > >> + > >> +#define GUEST_GICV3_RDIST_STRIDE 0x20000ULL > >> +#define GUEST_GICV3_RDIST_REGIONS 1 > >> + > >> +#define GUEST_GICV3_GICR0_BASE 0x03020000ULL /* vCPU0 - vCPU15 */ > >> +#define GUEST_GICV3_GICR0_SIZE 0x00200000ULL > >> + > >> /* 16MB == 4096 pages reserved for guest to use as a region to map its > >> * grant table in. > >> */ > >> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h > >> index 58b19e7..8da204e 100644 > >> --- a/xen/include/public/domctl.h > >> +++ b/xen/include/public/domctl.h > >> @@ -68,6 +68,19 @@ struct xen_domctl_createdomain { > >> typedef struct xen_domctl_createdomain xen_domctl_createdomain_t; > >> DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t); > >> > >> +#if defined(__arm__) || defined(__aarch64__) > >> +#define XEN_DOMCTL_CONFIG_GIC_DEFAULT 0 > >> +#define XEN_DOMCTL_CONFIG_GIC_V2 1 > >> +#define XEN_DOMCTL_CONFIG_GIC_V3 2 > >> +/* XEN_DOMCTL_configure_domain */ > >> +struct xen_domctl_arm_configuredomain { > >> + /* IN/OUT parameters */ > >> + uint8_t gic_version; > >> +}; > >> +typedef struct xen_domctl_arm_configuredomain > >> xen_domctl_arm_configuredomain_t; > >> +DEFINE_XEN_GUEST_HANDLE(xen_domctl_arm_configuredomain_t); > >> +#endif > >> + > >> /* XEN_DOMCTL_getdomaininfo */ > >> struct xen_domctl_getdomaininfo { > >> /* OUT variables. */ > >> @@ -1056,6 +1069,7 @@ struct xen_domctl { > >> #define XEN_DOMCTL_set_vcpu_msrs 73 > >> #define XEN_DOMCTL_setvnumainfo 74 > >> #define XEN_DOMCTL_psr_cmt_op 75 > >> +#define XEN_DOMCTL_arm_configure_domain 76 > >> #define XEN_DOMCTL_gdbsx_guestmemio 1000 > >> #define XEN_DOMCTL_gdbsx_pausevcpu 1001 > >> #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 > >> @@ -1064,6 +1078,9 @@ struct xen_domctl { > >> domid_t domain; > >> union { > >> struct xen_domctl_createdomain createdomain; > >> +#if defined(__arm__) || defined(__aarch64__) > >> + struct xen_domctl_arm_configuredomain configuredomain; > >> +#endif > >> struct xen_domctl_getdomaininfo getdomaininfo; > >> struct xen_domctl_getmemlist getmemlist; > >> struct xen_domctl_getpageframeinfo getpageframeinfo; > >> diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c > >> index 6d0fe72..846cf88 100644 > >> --- a/xen/xsm/flask/hooks.c > >> +++ b/xen/xsm/flask/hooks.c > >> @@ -727,6 +727,9 @@ static int flask_domctl(struct domain *d, int cmd) > >> case XEN_DOMCTL_psr_cmt_op: > >> return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__PSR_CMT_OP); > >> > >> + case XEN_DOMCTL_configure_domain: > >> + return current_has_perm(d, SECCLASS_DOMAIN2, > >> DOMAIN2__CONFIGURE_DOMAIN); > >> + > >> default: > >> printk("flask_domctl: Unknown op %d\n", cmd); > >> return -EPERM; > >> diff --git a/xen/xsm/flask/policy/access_vectors > >> b/xen/xsm/flask/policy/access_vectors > >> index de0c707..bfe2fa5 100644 > >> --- a/xen/xsm/flask/policy/access_vectors > >> +++ b/xen/xsm/flask/policy/access_vectors > >> @@ -216,6 +216,8 @@ class domain2 > >> get_vnumainfo > >> # XEN_DOMCTL_psr_cmt_op > >> psr_cmt_op > >> +# XEN_DOMCTL_configure_domain > >> + configure_domain > >> } > >> > >> # Similar to class domain, but primarily contains domctls related to HVM > >> domains > >> -- > >> 1.7.10.4 > >> > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@xxxxxxxxxxxxx > > http://lists.xen.org/xen-devel > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |