@@ -451,6 +451,16 @@
*/
#define LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS 1
+/*
+ * LIBXL_HAVE_BUILDINFO_XEN_ABI_FEATURE indicates that the
+ * libxl_xen_abi_feature enumeration is defined and that
+ * libxl_domain_build_info has feature_enable and _disable bitmaps
+ * of the specified width. These bitmaps are used to enable or disable
+ * features of the Xen ABI (enumerated by the new type) for a domain.
+ */
+#define LIBXL_HAVE_BUILDINFO_XEN_ABI_FEATURE 1
+#define LIBXL_BUILDINFO_FEATURE_ENABLE_DISABLE_WIDTH 64
+
/*
* libxl ABI compatibility
*
@@ -28,19 +28,27 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
unsigned int i;
uint32_t vuart_irq;
bool vuart_enabled = false;
+ libxl_domain_build_info *b_info = &d_config->b_info;
+ libxl_xen_abi_feature f = LIBXL_XEN_ABI_FEATURE_EVTCHN_UPCALL;
+
+ if (libxl_bitmap_test(&b_info->feature_enable, f)) {
+ LOG(ERROR, "unsupported Xen ABI feature '%s'",
+ libxl_xen_abi_feature_to_string(f));
+ return ERROR_FAIL;
+ }
/*
* If pl011 vuart is enabled then increment the nr_spis to allow allocation
* of SPI VIRQ for pl011.
*/
- if (d_config->b_info.arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART) {
+ if (b_info->arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART) {
nr_spis += (GUEST_VPL011_SPI - 32) + 1;
vuart_irq = GUEST_VPL011_SPI;
vuart_enabled = true;
}
- for (i = 0; i < d_config->b_info.num_irqs; i++) {
- uint32_t irq = d_config->b_info.irqs[i];
+ for (i = 0; i < b_info->num_irqs; i++) {
+ uint32_t irq = b_info->irqs[i];
uint32_t spi;
/*
@@ -72,7 +80,7 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
config->arch.nr_spis = nr_spis;
LOG(DEBUG, " - Allocate %u SPIs", nr_spis);
- switch (d_config->b_info.arch_arm.gic_version) {
+ switch (b_info->arch_arm.gic_version) {
case LIBXL_GIC_VERSION_DEFAULT:
config->arch.gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE;
break;
@@ -84,11 +92,11 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
break;
default:
LOG(ERROR, "Unknown GIC version %d",
- d_config->b_info.arch_arm.gic_version);
+ b_info->arch_arm.gic_version);
return ERROR_FAIL;
}
- switch (d_config->b_info.tee) {
+ switch (b_info->tee) {
case LIBXL_TEE_TYPE_NONE:
config->arch.tee_type = XEN_DOMCTL_CONFIG_TEE_NONE;
break;
@@ -97,7 +105,7 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
break;
default:
LOG(ERROR, "Unknown TEE type %d",
- d_config->b_info.tee);
+ b_info->tee);
return ERROR_FAIL;
}
@@ -587,6 +587,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
struct xs_permissions noperm[1];
xs_transaction_t t = 0;
libxl_vminfo *vm_list;
+ libxl_xen_abi_feature f;
/* convenience aliases */
libxl_domain_create_info *info = &d_config->c_info;
@@ -607,9 +608,38 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
.max_evtchn_port = b_info->event_channels,
.max_grant_frames = b_info->max_grant_frames,
.max_maptrack_frames = b_info->max_maptrack_frames,
- .flags = XEN_DOMCTL_CDF_evtchn_fifo,
};
+ libxl_for_each_set_bit(f, b_info->feature_enable) {
+ if (!libxl_xen_abi_feature_to_string(f)) { /* check validity */
+ LOGED(ERROR, *domid, "unknown Xen ABI feature enabled");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ if (libxl_bitmap_test(&b_info->feature_disable, f)) {
+ LOGED(ERROR, *domid, "Xen ABI feature '%s' both enabled and disabled",
+ libxl_xen_abi_feature_to_string(f));
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ LOGD(DETAIL, *domid, "enable feature: '%s'",
+ libxl_xen_abi_feature_to_string(f));
+ }
+
+ libxl_for_each_set_bit(f, b_info->feature_disable) {
+ if (!libxl_xen_abi_feature_to_string(f)) { /* check validity */
+ LOGED(ERROR, *domid, "unknown Xen ABI feature disabled");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ LOGD(DETAIL, *domid, "disable feature: '%s'",
+ libxl_xen_abi_feature_to_string(f));
+ }
+
+ if (!libxl_bitmap_test(&b_info->feature_disable,
+ LIBXL_XEN_ABI_FEATURE_EVTCHN_FIFO))
+ create.flags |= XEN_DOMCTL_CDF_evtchn_fifo;
+
if (info->type != LIBXL_DOMAIN_TYPE_PV) {
create.flags |= XEN_DOMCTL_CDF_hvm;
@@ -477,6 +477,11 @@ libxl_tee_type = Enumeration("tee_type", [
(1, "optee")
], init_val = "LIBXL_TEE_TYPE_NONE")
+libxl_xen_abi_feature = Enumeration("xen_abi_feature", [
+ (0, "evtchn_fifo"),
+ (1, "evtchn_upcall")
+ ])
+
libxl_rdm_reserve = Struct("rdm_reserve", [
("strategy", libxl_rdm_reserve_strategy),
("policy", libxl_rdm_reserve_policy),
@@ -559,6 +564,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
("apic", libxl_defbool),
("dm_restrict", libxl_defbool),
("tee", libxl_tee_type),
+ ("feature_enable", libxl_bitmap),
+ ("feature_disable", libxl_bitmap),
("u", KeyedUnion(None, libxl_domain_type, "type",
[("hvm", Struct(None, [("firmware", string),
("bios", libxl_bios_type),
@@ -6,9 +6,19 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
struct xen_domctl_createdomain *config)
{
libxl_domain_create_info *info = &d_config->c_info;
+ libxl_domain_build_info *b_info = &d_config->b_info;
+ libxl_xen_abi_feature f = LIBXL_XEN_ABI_FEATURE_EVTCHN_UPCALL;
- if (info->type == LIBXL_DOMAIN_TYPE_HVM)
- config->flags |= XEN_DOMCTL_CDF_evtchn_upcall;
+ if (info->type != LIBXL_DOMAIN_TYPE_HVM &&
+ libxl_bitmap_test(&b_info->feature_enable, f)) {
+ LOG(ERROR, "unsupported Xen ABI feature '%s'",
+ libxl_xen_abi_feature_to_string(f));
+ return ERROR_FAIL;
+ }
+
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM &&
+ !libxl_bitmap_test(&b_info->feature_disable, f))
+ config->flags |= XEN_DOMCTL_CDF_evtchn_upcall;
switch(info->type) {
case LIBXL_DOMAIN_TYPE_HVM: