mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
arm: Allow the user to specify the GIC version
A platform may have a GIC compatible with previous version of the device. This is allow to virtualize an unmodified OS on new hardware if the GIC is compatible with older version. When a guest is created, the vGIC will emulate same version as the hardware. Although, the user can specify in the configuration file the preferred version (currently only GICv2 and GICv3 are supported). Signed-off-by: Julien Grall <julien.grall@citrix.com> Cc: Ian Jackson <ian.jackson@eu.citrix.com> Cc: Wei Liu <wei.liu2@citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
1 parent
7617641fe8
commit
90a100f86c
11 files changed
+141
-21
No files matched your search
@@ -1680,6 +1680,40 @@ The default is B<en-us>.
|
||||
|
||||
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
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
*/
|
||||
#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
|
||||
*
|
||||
|
||||
@@ -21,6 +21,12 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
|
||||
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,
|
||||
|
||||
+34
-1
@@ -61,7 +61,40 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -527,6 +527,10 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
|
||||
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");
|
||||
|
||||
@@ -380,6 +380,12 @@ libxl_vnode_info = Struct("vnode_info", [
|
||||
("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),
|
||||
@@ -492,6 +498,11 @@ libxl_domain_build_info = Struct("domain_build_info",[
|
||||
])),
|
||||
("invalid", None),
|
||||
], keyvar_init_val = "LIBXL_DOMAIN_TYPE_INVALID")),
|
||||
|
||||
|
||||
("arch_arm", Struct(None, [("gic_version", libxl_gic_version),
|
||||
])),
|
||||
|
||||
], dir=DIR_IN
|
||||
)
|
||||
|
||||
|
||||
@@ -10,6 +10,13 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
|
||||
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) {
|
||||
|
||||
@@ -2257,6 +2257,15 @@ skip_vfb:
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+27
-18
@@ -531,7 +531,6 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
|
||||
struct xen_arch_domainconfig *config)
|
||||
{
|
||||
int rc;
|
||||
uint8_t gic_version;
|
||||
|
||||
d->arch.relmem = RELMEM_not_started;
|
||||
|
||||
@@ -560,28 +559,38 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
|
||||
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 GIC_V2:
|
||||
gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
|
||||
|
||||
case XEN_DOMCTL_CONFIG_GIC_V2:
|
||||
d->arch.vgic.version = GIC_V2;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
+2
-2
@@ -81,7 +81,7 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
|
||||
|
||||
d->arch.vgic.nr_spis = nr_spis;
|
||||
|
||||
switch ( gic_hw_version() )
|
||||
switch ( d->arch.vgic.version )
|
||||
{
|
||||
#ifdef HAS_GICV3
|
||||
case GIC_V3:
|
||||
@@ -95,7 +95,7 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,8 @@ struct arch_domain
|
||||
} virt_timer_base;
|
||||
|
||||
struct {
|
||||
/* Version of the vGIC */
|
||||
enum gic_version version;
|
||||
/* GIC HW version specific vGIC driver handler */
|
||||
const struct vgic_ops *handler;
|
||||
/*
|
||||
|
||||