diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index 30c401588f..b19c25c8d1 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -3088,8 +3088,8 @@ GICv2 compatibility mode. =item B -Emulate the same version as the native GIC hardware used by the host where -the domain was created. +Let the toolstack choose the GIC version: GICv3 if the host supports it, +otherwise GICv2. This is the default when C is not specified. =back diff --git a/tools/include/xen-tools/arm-arch-capabilities.h b/tools/include/xen-tools/arm-arch-capabilities.h index 4aa4c6c34a..21e3c73bd1 100644 --- a/tools/include/xen-tools/arm-arch-capabilities.h +++ b/tools/include/xen-tools/arm-arch-capabilities.h @@ -6,6 +6,7 @@ #ifndef ARM_ARCH_CAPABILITIES_H #define ARM_ARCH_CAPABILITIES_H +#include #include #include @@ -25,4 +26,24 @@ unsigned int arch_capabilities_arm_sve(unsigned int arch_capabilities) #endif } +static inline +bool arch_capabilities_arm_gic_v2(unsigned int arch_capabilities) +{ +#if defined(__arm__) || defined(__aarch64__) + return MASK_EXTR(arch_capabilities, XEN_SYSCTL_PHYSCAP_ARM_GIC_V2); +#else + return false; +#endif +} + +static inline +bool arch_capabilities_arm_gic_v3(unsigned int arch_capabilities) +{ +#if defined(__arm__) || defined(__aarch64__) + return MASK_EXTR(arch_capabilities, XEN_SYSCTL_PHYSCAP_ARM_GIC_V3); +#else + return false; +#endif +} + #endif /* ARM_ARCH_CAPABILITIES_H */ diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index 7e9f8a1bc3..b9c0c820d6 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -196,9 +196,6 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, LOG(DEBUG, " - Allocate %u SPIs", config->arch.nr_spis); switch (d_config->b_info.arch_arm.gic_version) { - case LIBXL_GIC_VERSION_DEFAULT: - config->arch.gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE; - break; case LIBXL_GIC_VERSION_V2: config->arch.gic_version = XEN_DOMCTL_CONFIG_GIC_V2; break; @@ -1794,12 +1791,52 @@ int libxl__arch_domain_build_info_setdefault(libxl__gc *gc, libxl_domain_build_info *b_info, const libxl_physinfo *physinfo) { + bool has_v3 = arch_capabilities_arm_gic_v3(physinfo->arch_capabilities); + bool has_v2 = arch_capabilities_arm_gic_v2(physinfo->arch_capabilities); + /* ACPI is disabled by default */ libxl_defbool_setdefault(&b_info->acpi, false); /* Trapping of unmapped accesses enabled by default. */ libxl_defbool_setdefault(&b_info->trap_unmapped_accesses, true); + /* + * Resolve the GIC version against the host capabilities reported by + * XEN_SYSCTL_physinfo. If the user didn't request a specific version, pick + * the best one available. Otherwise validate the requested version here, + * so a bad request fails early instead of in the hypervisor. + */ + switch (b_info->arch_arm.gic_version) { + case LIBXL_GIC_VERSION_DEFAULT: + if (has_v3) { + b_info->arch_arm.gic_version = LIBXL_GIC_VERSION_V3; + } else if (has_v2) { + b_info->arch_arm.gic_version = LIBXL_GIC_VERSION_V2; + } else { + LOG(ERROR, "No supported GIC version found on this host"); + return ERROR_FAIL; + } + break; + + case LIBXL_GIC_VERSION_V3: + if (!has_v3) { + LOG(ERROR, "GICv3 requested but not supported on this host"); + return ERROR_FAIL; + } + break; + + case LIBXL_GIC_VERSION_V2: + if (!has_v2) { + LOG(ERROR, "GICv2 requested but not supported on this host"); + return ERROR_FAIL; + } + break; + + default: + LOG(ERROR, "Unknown GIC version %d", b_info->arch_arm.gic_version); + return ERROR_FAIL; + } + /* Sanitise SVE parameter */ if (b_info->arch_arm.sve_vl) { unsigned int max_sve_vl = diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 7a4bf54597..0127b4b1b7 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -163,7 +163,23 @@ static PyObject *pyxc_domain_create(XcObject *self, ~(XEN_X86_EMU_VPCI | XEN_X86_EMU_USE_PIRQ); #elif defined (__arm__) || defined(__aarch64__) - config.arch.gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE; + { + xc_physinfo_t pinfo; + + if ( xc_physinfo(self->xc_handle, &pinfo) != 0 ) + return pyxc_error_to_exception(self->xc_handle); + + if ( arch_capabilities_arm_gic_v3(pinfo.arch_capabilities) ) + config.arch.gic_version = XEN_DOMCTL_CONFIG_GIC_V3; + else if ( arch_capabilities_arm_gic_v2(pinfo.arch_capabilities) ) + config.arch.gic_version = XEN_DOMCTL_CONFIG_GIC_V2; + else + { + errno = EINVAL; + PyErr_SetFromErrno(xc_error_obj); + return NULL; + } + } #else #error Architecture not supported #endif