See L<qemu(1)> for more information.
+=head2 Architecture Specific options
+
+=head3 ARM
+
+=over 4
+
+=item B<gic_version="vN">
+
+Version of the GIC emulated for the guest. Currently, the following
+versions are supported:
+
+=over 4
+
+=item B<v2>
+
+Emulate a GICv2
+
+=item B<v3>
+
+Emulate a GICv3. Note that the emulated GIC does not support the
+GICv2 compatibility mode.
+
+=item B<default>
+
+Emulate the same version as the native GIC hardware used by host where
+the domain was created.
+
+=back
+
+This requires hardware compatibility with the requested version. Either
+natively or via hardware backwards compatibility support.
+
+=back
+
=head1 SEE ALSO
=over 4
*/
#define LIBXL_HAVE_DEVICETREE_PASSTHROUGH 1
+/*
+ * libxl_domain_build_info has the arm.gic_version field.
+ */
+#define LIBXL_HAVE_BUILDINFO_ARM_GIC_VERSION 1
+
/*
* libxl ABI compatibility
*
libxl_domain_config *d_config,
xc_domain_configuration_t *xc_config);
+/* save the arch specific configuration for the domain */
+_hidden
+int libxl__arch_domain_save_config(libxl__gc *gc,
+ libxl_domain_config *d_config,
+ const xc_domain_configuration_t *xc_config);
+
/* arch specific internal domain creation function */
_hidden
int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
xc_config->nr_spis = nr_spis;
LOG(DEBUG, " - Allocate %u SPIs", nr_spis);
- xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE;
+ switch (d_config->b_info.arch_arm.gic_version) {
+ case LIBXL_GIC_VERSION_DEFAULT:
+ xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE;
+ break;
+ case LIBXL_GIC_VERSION_V2:
+ xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
+ break;
+ case LIBXL_GIC_VERSION_V3:
+ xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
+ break;
+ default:
+ LOG(ERROR, "Unknown GIC version %d\n",
+ d_config->b_info.arch_arm.gic_version);
+ return ERROR_FAIL;
+ }
+
+ return 0;
+}
+
+int libxl__arch_domain_save_config(libxl__gc *gc,
+ libxl_domain_config *d_config,
+ const xc_domain_configuration_t *xc_config)
+{
+ switch (xc_config->gic_version) {
+ case XEN_DOMCTL_CONFIG_GIC_V2:
+ d_config->b_info.arch_arm.gic_version = LIBXL_GIC_VERSION_V2;
+ break;
+ case XEN_DOMCTL_CONFIG_GIC_V3:
+ d_config->b_info.arch_arm.gic_version = LIBXL_GIC_VERSION_V3;
+ break;
+ default:
+ LOG(ERROR, "Unexpected gic version %u\n", xc_config->gic_version);
+ return ERROR_FAIL;
+ }
return 0;
}
goto out;
}
+ rc = libxl__arch_domain_save_config(gc, d_config, xc_config);
+ if (rc < 0)
+ goto out;
+
ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
if (ret < 0) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "domain move fail");
("vcpus", libxl_bitmap), # vcpus in this node
])
+libxl_gic_version = Enumeration("gic_version", [
+ (0, "DEFAULT"),
+ (0x20, "v2"),
+ (0x30, "v3")
+ ], init_val = "LIBXL_GIC_VERSION_DEFAULT")
+
libxl_domain_build_info = Struct("domain_build_info",[
("max_vcpus", integer),
("avail_vcpus", libxl_bitmap),
])),
("invalid", None),
], keyvar_init_val = "LIBXL_DOMAIN_TYPE_INVALID")),
+
+
+ ("arch_arm", Struct(None, [("gic_version", libxl_gic_version),
+ ])),
+
], dir=DIR_IN
)
return 0;
}
+int libxl__arch_domain_save_config(libxl__gc *gc,
+ libxl_domain_config *d_config,
+ const xc_domain_configuration_t *xc_config)
+{
+ return 0;
+}
+
static const char *e820_names(int type)
{
switch (type) {
}
}
+ if (!xlu_cfg_get_string (config, "gic_version", &buf, 1)) {
+ e = libxl_gic_version_from_string(buf, &b_info->arch_arm.gic_version);
+ if (e) {
+ fprintf(stderr,
+ "Unknown gic_version \"%s\" specified\n", buf);
+ exit(-ERROR_FAIL);
+ }
+ }
+
xlu_cfg_destroy(config);
}
struct xen_arch_domainconfig *config)
{
int rc;
- uint8_t gic_version;
d->arch.relmem = RELMEM_not_started;
if ( (rc = p2m_alloc_table(d)) != 0 )
goto fail;
- /*
- * Currently the vGIC is emulating the same version of the
- * hardware GIC. Only the value XEN_DOMCTL_CONFIG_GIC_NATIVE
- * is allowed. The DOMCTL will return the actual version of the
- * GIC.
- */
- rc = -EOPNOTSUPP;
- if ( config->gic_version != XEN_DOMCTL_CONFIG_GIC_NATIVE )
- goto fail;
-
- switch ( gic_hw_version() )
+ switch ( config->gic_version )
{
- case GIC_V3:
- gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
+ case XEN_DOMCTL_CONFIG_GIC_NATIVE:
+ switch ( gic_hw_version () )
+ {
+ case GIC_V2:
+ config->gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
+ d->arch.vgic.version = GIC_V2;
+ break;
+
+ case GIC_V3:
+ config->gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
+ d->arch.vgic.version = GIC_V3;
+ break;
+
+ default:
+ BUG();
+ }
+ break;
+
+ case XEN_DOMCTL_CONFIG_GIC_V2:
+ d->arch.vgic.version = GIC_V2;
break;
- case GIC_V2:
- gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
+
+ case XEN_DOMCTL_CONFIG_GIC_V3:
+ d->arch.vgic.version = GIC_V3;
break;
+
default:
- BUG();
+ rc = -EOPNOTSUPP;
+ goto fail;
}
- config->gic_version = gic_version;
if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 )
goto fail;
d->arch.vgic.nr_spis = nr_spis;
- switch ( gic_hw_version() )
+ switch ( d->arch.vgic.version )
{
#ifdef HAS_GICV3
case GIC_V3:
break;
default:
printk(XENLOG_G_ERR "d%d: Unknown vGIC version %u\n",
- d->domain_id, gic_hw_version());
+ d->domain_id, d->arch.vgic.version);
return -ENODEV;
}
} virt_timer_base;
struct {
+ /* Version of the vGIC */
+ enum gic_version version;
/* GIC HW version specific vGIC driver handler */
const struct vgic_ops *handler;
/*