@@ -2901,6 +2901,16 @@ option.
If using this option is necessary to fix an issue, please report a bug.
+=item B<ext_dest_id=BOOLEAN>
+
+(HVM/PVH only) Signal the hypervisor whether the guest should be allowed to use
+extended destination ID for interrupt messages. Such feature allow expanding
+the target APIC ID from 8 to 15bits without requiring the usage of an emulated
+IOMMU with interrupt remapping. Note this requires guest support and might not
+be exposed to the guest even if explicitly set due to other constrains.
+
+Default: enabled
+
=back
=head1 SEE ALSO
@@ -527,6 +527,14 @@
*/
#define LIBXL_HAVE_MAX_GRANT_VERSION 1
+/*
+ * LIBXL_HAVE_X86_EXT_DEST_ID indicates the toolstack can signal to the
+ * hypervisor whether the domain wants to use the extended destination ID mode
+ * for interrupt messages. This is done by setting the libxl_domain_build_info
+ * arch_x86.ext_dest_id field.
+ */
+#define LIBXL_HAVE_X86_EST_DEST_ID 1
+
/*
* libxl ABI compatibility
*
@@ -2330,6 +2330,12 @@ int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
*/
libxl_defbool_setdefault(&d_config->b_info.arch_x86.msr_relaxed, true);
+ /*
+ * Do not enable the extended destination ID for restored domains unless
+ * explicitly set.
+ */
+ libxl_defbool_setdefault(&d_config->b_info.arch_x86.ext_dest_id, false);
+
return do_domain_create(ctx, d_config, domid, restore_fd, send_back_fd,
params, ao_how, aop_console_how);
}
@@ -648,6 +648,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
("vuart", libxl_vuart_type),
])),
("arch_x86", Struct(None, [("msr_relaxed", libxl_defbool),
+ ("ext_dest_id", libxl_defbool),
])),
# Alternate p2m is not bound to any architecture or guest type, as it is
# supported by x86 HVM and ARM support is planned.
@@ -14,6 +14,11 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
break;
case LIBXL_DOMAIN_TYPE_PV:
config->arch.emulation_flags = 0;
+ if (libxl_defbool_val(d_config->b_info.arch_x86.ext_dest_id))
+ {
+ LOG(ERROR, "Extended Destination ID not supported for PV guests");
+ return ERROR_INVAL;
+ }
break;
default:
abort();
@@ -22,6 +27,8 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
config->arch.misc_flags = 0;
if (libxl_defbool_val(d_config->b_info.arch_x86.msr_relaxed))
config->arch.misc_flags |= XEN_X86_MSR_RELAXED;
+ if (libxl_defbool_val(d_config->b_info.arch_x86.ext_dest_id))
+ config->arch.misc_flags |= XEN_X86_EXT_DEST_ID;
return 0;
}
@@ -824,6 +831,8 @@ void libxl__arch_domain_build_info_setdefault(libxl__gc *gc,
{
libxl_defbool_setdefault(&b_info->acpi, true);
libxl_defbool_setdefault(&b_info->arch_x86.msr_relaxed, false);
+ libxl_defbool_setdefault(&b_info->arch_x86.ext_dest_id,
+ b_info->type != LIBXL_DOMAIN_TYPE_PV);
}
int libxl__arch_passthrough_mode_setdefault(libxl__gc *gc,
@@ -880,6 +889,9 @@ void libxl__arch_update_domain_config(libxl__gc *gc,
*/
libxl_defbool_setdefault(&dst->b_info.arch_x86.msr_relaxed,
libxl_defbool_val(src->b_info.arch_x86.msr_relaxed));
+ /* Force Extended Destination ID so it's part of the migration data. */
+ libxl_defbool_setdefault(&dst->b_info.arch_x86.ext_dest_id,
+ libxl_defbool_val(src->b_info.arch_x86.ext_dest_id));
}
/*
@@ -2761,6 +2761,9 @@ skip_usbdev:
xlu_cfg_get_defbool(config, "vpmu", &b_info->vpmu, 0);
+ xlu_cfg_get_defbool(config, "ext_dest_id", &b_info->arch_x86.ext_dest_id,
+ 0);
+
xlu_cfg_destroy(config);
}
@@ -685,12 +685,19 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
}
}
- if ( config->arch.misc_flags & ~XEN_X86_MSR_RELAXED )
+ if ( config->arch.misc_flags &
+ ~(XEN_X86_MSR_RELAXED | XEN_X86_EXT_DEST_ID) )
{
dprintk(XENLOG_INFO, "Invalid arch misc flags %#x\n",
config->arch.misc_flags);
return -EINVAL;
}
+ if ( !hvm && (config->arch.misc_flags & XEN_X86_EXT_DEST_ID) )
+ {
+ dprintk(XENLOG_INFO,
+ "Extended Destination ID only supported for HVM\n");
+ return -EINVAL;
+ }
return 0;
}
@@ -862,6 +869,7 @@ int arch_domain_create(struct domain *d,
domain_cpu_policy_changed(d);
d->arch.msr_relaxed = config->arch.misc_flags & XEN_X86_MSR_RELAXED;
+ d->arch.ext_dest_id = config->arch.misc_flags & XEN_X86_EXT_DEST_ID;
return 0;
@@ -424,6 +424,9 @@ static void vioapic_deliver(struct hvm_vioapic *vioapic, unsigned int pin)
ASSERT(spin_is_locked(&d->arch.hvm.irq_lock));
+ if ( d->arch.ext_dest_id )
+ dest |= vioapic->redirtbl[pin].fields.virt_ext_dest_id << 8;
+
HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
"dest=%x dest_mode=%x delivery_mode=%x "
"vector=%x trig_mode=%x",
@@ -440,6 +440,9 @@ struct arch_domain
/* Don't unconditionally inject #GP for unhandled MSRs. */
bool msr_relaxed;
+ /* Use the Extended Destination ID to expand APIC ID. */
+ bool ext_dest_id;
+
/* Emulated devices enabled bitmap. */
uint32_t emulation_flags;
} __cacheline_aligned;
@@ -782,6 +782,7 @@ static struct domain *__init create_dom0(const module_t *image,
dom0_cfg.arch.emulation_flags |=
XEN_X86_EMU_LAPIC | XEN_X86_EMU_IOAPIC | XEN_X86_EMU_VPCI;
+ dom0_cfg.arch.misc_flags |= XEN_X86_EXT_DEST_ID;
}
if ( iommu_enabled )
@@ -376,7 +376,9 @@ union vioapic_redir_entry
uint8_t trig_mode:1;
uint8_t mask:1;
uint8_t reserve:7;
- uint8_t reserved[4];
+ uint8_t reserved[3];
+ uint8_t :1;
+ uint8_t virt_ext_dest_id:7;
uint8_t dest_id;
} fields;
};
@@ -317,6 +317,8 @@ struct xen_arch_domainconfig {
* doesn't allow the guest to read or write to the underlying MSR.
*/
#define XEN_X86_MSR_RELAXED (1u << 0)
+/* Select whether to use Extended Destination ID for interrupt messages. */
+#define XEN_X86_EXT_DEST_ID (1u << 1)
uint32_t misc_flags;
};
@@ -38,7 +38,7 @@
#include "hvm/save.h"
#include "memory.h"
-#define XEN_DOMCTL_INTERFACE_VERSION 0x00000014
+#define XEN_DOMCTL_INTERFACE_VERSION 0x00000015
/*
* NB. xen_domctl.domain is an IN/OUT parameter for this operation.
Such field uses bits 55:48, but for the purposes the register will be used use bits 55:49 instead. Bit 48 is used to signal an RTE entry is in remappable format which is not supported by the vIO-APIC. Use the extended destination ID to store the high bits from the destination ID, thus expanding the size of the destination ID field to 15 bits, allowing an IO-APIC to target APIC IDs up to 32768. A description of the feature can be found at: http://david.woodhou.se/15-bit-msi.pdf Note this is already supported by QEMU/KVM and HyperV. Introduce an option in xl.cfg to allow switching off the feature. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- Changes since v1: - Expand commit message, add reference document. - Add xl option to disable the feature. --- docs/man/xl.cfg.5.pod.in | 10 ++++++++++ tools/include/libxl.h | 8 ++++++++ tools/libs/light/libxl_create.c | 6 ++++++ tools/libs/light/libxl_types.idl | 1 + tools/libs/light/libxl_x86.c | 12 ++++++++++++ tools/xl/xl_parse.c | 3 +++ xen/arch/x86/domain.c | 10 +++++++++- xen/arch/x86/hvm/vioapic.c | 3 +++ xen/arch/x86/include/asm/domain.h | 3 +++ xen/arch/x86/setup.c | 1 + xen/include/public/arch-x86/hvm/save.h | 4 +++- xen/include/public/arch-x86/xen.h | 2 ++ xen/include/public/domctl.h | 2 +- 13 files changed, 62 insertions(+), 3 deletions(-)