[PATCH 0/5] Xen: Add support for xl.cfg passthrough setting

Hi All, Note: This series is based on Marek's patches adding support for e820_host https://www.redhat.com/archives/libvir-list/2020-April/msg00633.html which I've ACK'ed, but am waiting to commit until this related setting is hashed out. This series adds support for Xen's xl.cfg(5) 'passthrough' setting. Starting with xen 4.13 this setting must be enabled in order to assign PCI passthrough devices to a guest. libxl will enable it automatically if the guest config has PCI devices at creation time, but otherwise 'passthrough' must be enabled to hotplug PCI devices. The passthrough setting is mapped to a xen hypervisor feature of the same name. Xen hypervisor features were recently added by the series mentioned above. Jim Fehlig (5): conf: add xen hypervisor feature 'passthrough' libxl: make use of passthrough hypervisor feature libxl: refactor cpu and hypervisor feature parser/formatter xenconfig: Add support for 'passthrough' hypervisor feature tests: check conversion of passthrough hypervisor feature docs/formatdomain.html.in | 7 ++ docs/schemas/domaincommon.rng | 12 ++ src/conf/domain_conf.c | 115 ++++++++++++++---- src/conf/domain_conf.h | 11 ++ src/libvirt_private.syms | 2 + src/libxl/libxl_conf.c | 21 ++++ src/libxl/xen_common.c | 86 ++++++++++--- .../test-fullvirt-hypervisor-features.cfg | 26 ++++ .../test-fullvirt-hypervisor-features.xml | 50 ++++++++ .../xlconfigdata/test-paravirt-e820_host.cfg | 1 + .../xlconfigdata/test-paravirt-e820_host.xml | 1 + tests/xlconfigtest.c | 3 + 12 files changed, 290 insertions(+), 45 deletions(-) create mode 100644 tests/xlconfigdata/test-fullvirt-hypervisor-features.cfg create mode 100644 tests/xlconfigdata/test-fullvirt-hypervisor-features.xml -- 2.26.0

'passthrough' is Xen-Specific guest configuration option new to Xen 4.13 that enables IOMMU mappings for a guest and hence whether it supports PCI passthrough. The default is disabled. See the xl.cfg(5) man page and xen.git commit babde47a3fe for more details. The default state of disabled prevents hotlugging PCI devices. However, if the guest configuration contains a PCI passthrough device at time of creation, libxl will automatically enable 'passthrough' and subsequent hotplugging of PCI devices will also be possible. It is not possible to unconditionally enable 'passthrough' since it would introduce a migration incompatibility due to guest ABI change. Instead, introduce another Xen hypervisor feature that can be used to enable guest PCI passthrough <features> <xen> <passthrough state='on'/> </xen> </features> To allow finer control over how IOMMU maps to guest P2M table, the passthrough element also supports a 'mode' attribute with values restricted to snyc_pt and share_pt, similar to xl.cfg(5) 'passthrough' setting . Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- docs/formatdomain.html.in | 7 +++ docs/schemas/domaincommon.rng | 12 ++++ src/conf/domain_conf.c | 115 ++++++++++++++++++++++++++-------- src/conf/domain_conf.h | 11 ++++ 4 files changed, 119 insertions(+), 26 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 81060d6730..9ccae54e04 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2063,6 +2063,7 @@ </kvm> <xen> <e820_host state='on'/> + <passthrough state='on' mode='share_pt'/> </xen> <pvspinlock state='on'/> <gic version='2'/> @@ -2260,6 +2261,12 @@ <td>on, off</td> <td><span class="since">6.3.0</span></td> </tr> + <tr> + <td>passthrough</td> + <td>Enable IOMMU mappings allowing PCI passthrough)</td> + <td>on, off; mode - optional string sync_pt or share_pt</td> + <td><span class="since">6.3.0</span></td> + </tr> </table> </dd> <dt><code>pmu</code></dt> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 2b5f844658..a6f6e8ab83 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -6349,6 +6349,18 @@ <ref name="featurestate"/> </element> </optional> + <optional> + <element name="passthrough"> + <ref name="featurestate"/> + <optional> + <attribute name="mode"> + <data type="string"> + <param name='pattern'>(sync_pt|share_pt)</param> + </data> + </attribute> + </optional> + </element> + </optional> </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index dabbceb265..9f3362c934 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -209,7 +209,15 @@ VIR_ENUM_IMPL(virDomainKVM, VIR_ENUM_IMPL(virDomainXen, VIR_DOMAIN_XEN_LAST, - "e820_host" + "e820_host", + "passthrough", +); + +VIR_ENUM_IMPL(virDomainXenPassthroughMode, + VIR_DOMAIN_XEN_PASSTHROUGH_MODE_LAST, + "default", + "sync_pt", + "share_pt", ); VIR_ENUM_IMPL(virDomainMsrsUnknown, @@ -21182,6 +21190,8 @@ virDomainDefParseXML(xmlDocPtr xml, if (def->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) { int feature; int value; + g_autofree char *ptval = NULL; + if ((n = virXPathNodeSet("./features/xen/*", ctxt, &nodes)) < 0) goto error; @@ -21194,27 +21204,53 @@ virDomainDefParseXML(xmlDocPtr xml, goto error; } + if (!(tmp = virXMLPropString(nodes[i], "state"))) { + virReportError(VIR_ERR_XML_ERROR, + _("missing 'state' attribute for " + "Xen feature '%s'"), + nodes[i]->name); + goto error; + } + + if ((value = virTristateSwitchTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid value of state argument " + "for Xen feature '%s'"), + nodes[i]->name); + goto error; + } + + VIR_FREE(tmp); + def->xen_features[feature] = value; + switch ((virDomainXen) feature) { case VIR_DOMAIN_XEN_E820_HOST: - if (!(tmp = virXMLPropString(nodes[i], "state"))) { - virReportError(VIR_ERR_XML_ERROR, - _("missing 'state' attribute for " - "Xen feature '%s'"), - nodes[i]->name); - goto error; - } + break; - if ((value = virTristateSwitchTypeFromString(tmp)) < 0) { + case VIR_DOMAIN_XEN_PASSTHROUGH: + if (value != VIR_TRISTATE_SWITCH_ON) + break; + + if ((ptval = virXMLPropString(nodes[i], "mode"))) { + int mode = virDomainXenPassthroughModeTypeFromString(ptval); + + if (mode < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("invalid value of state argument " - "for Xen feature '%s'"), - nodes[i]->name); + _("unsupported mode '%s' for Xen passthrough feature"), + ptval); goto error; } - VIR_FREE(tmp); - def->xen_features[feature] = value; - break; + if (mode != VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SYNC_PT && + mode != VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SHARE_PT) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'mode' attribute for Xen feature " + "'passthrough' must be 'sync_pt' or 'share_pt'")); + goto error; + } + def->xen_passthrough_mode = mode; + } + break; /* coverity[dead_error_begin] */ case VIR_DOMAIN_XEN_LAST: @@ -23400,18 +23436,28 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, /* xen */ if (src->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) { for (i = 0; i < VIR_DOMAIN_XEN_LAST; i++) { + if (src->xen_features[i] != dst->xen_features[i]) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("State of Xen feature '%s' differs: " + "source: '%s', destination: '%s'"), + virDomainXenTypeToString(i), + virTristateSwitchTypeToString(src->xen_features[i]), + virTristateSwitchTypeToString(dst->xen_features[i])); + return false; + } switch ((virDomainXen) i) { case VIR_DOMAIN_XEN_E820_HOST: - if (src->xen_features[i] != dst->xen_features[i]) { + break; + + case VIR_DOMAIN_XEN_PASSTHROUGH: + if (src->xen_passthrough_mode != dst->xen_passthrough_mode) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("State of Xen feature '%s' differs: " + _("'mode' of Xen passthrough feature differs: " "source: '%s', destination: '%s'"), - virDomainXenTypeToString(i), - virTristateSwitchTypeToString(src->xen_features[i]), - virTristateSwitchTypeToString(dst->xen_features[i])); + virDomainXenPassthroughModeTypeToString(src->xen_passthrough_mode), + virDomainXenPassthroughModeTypeToString(dst->xen_passthrough_mode)); return false; } - break; /* coverity[dead_error_begin] */ @@ -29047,13 +29093,30 @@ virDomainDefFormatFeatures(virBufferPtr buf, virBufferAddLit(&childBuf, "<xen>\n"); virBufferAdjustIndent(&childBuf, 2); for (j = 0; j < VIR_DOMAIN_XEN_LAST; j++) { + if (def->xen_features[j] == VIR_TRISTATE_SWITCH_ABSENT) + continue; + + virBufferAsprintf(&childBuf, "<%s state='%s'", + virDomainXenTypeToString(j), + virTristateSwitchTypeToString( + def->xen_features[j])); + switch ((virDomainXen) j) { case VIR_DOMAIN_XEN_E820_HOST: - if (def->xen_features[j]) - virBufferAsprintf(&childBuf, "<%s state='%s'/>\n", - virDomainXenTypeToString(j), - virTristateSwitchTypeToString( - def->xen_features[j])); + virBufferAddLit(&childBuf, "/>\n"); + break; + case VIR_DOMAIN_XEN_PASSTHROUGH: + if (def->xen_features[j] != VIR_TRISTATE_SWITCH_ON) { + virBufferAddLit(&childBuf, "/>\n"); + break; + } + if (def->xen_passthrough_mode == VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SYNC_PT || + def->xen_passthrough_mode == VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SHARE_PT) { + virBufferEscapeString(&childBuf, " mode='%s'/>\n", + virDomainXenPassthroughModeTypeToString(def->xen_passthrough_mode)); + } else { + virBufferAddLit(&childBuf, "/>\n"); + } break; /* coverity[dead_error_begin] */ diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 0374494076..dabcd5197d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1862,10 +1862,19 @@ typedef enum { typedef enum { VIR_DOMAIN_XEN_E820_HOST = 0, + VIR_DOMAIN_XEN_PASSTHROUGH, VIR_DOMAIN_XEN_LAST } virDomainXen; +typedef enum { + VIR_DOMAIN_XEN_PASSTHROUGH_MODE_DEFAULT = 0, + VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SYNC_PT, + VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SHARE_PT, + + VIR_DOMAIN_XEN_PASSTHROUGH_MODE_LAST +} virDomainXenPassthroughMode; + typedef enum { VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT = 0, VIR_DOMAIN_CAPABILITIES_POLICY_ALLOW, @@ -2492,6 +2501,7 @@ struct _virDomainDef { int kvm_features[VIR_DOMAIN_KVM_LAST]; int msrs_features[VIR_DOMAIN_MSRS_LAST]; int xen_features[VIR_DOMAIN_XEN_LAST]; + int xen_passthrough_mode; unsigned int hyperv_spinlocks; int hyperv_stimer_direct; virGICVersion gic_version; @@ -3538,6 +3548,7 @@ VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy); VIR_ENUM_DECL(virDomainHyperv); VIR_ENUM_DECL(virDomainKVM); VIR_ENUM_DECL(virDomainXen); +VIR_ENUM_DECL(virDomainXenPassthroughMode); VIR_ENUM_DECL(virDomainMsrsUnknown); VIR_ENUM_DECL(virDomainRNGModel); VIR_ENUM_DECL(virDomainRNGBackend); -- 2.26.0

Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/libxl/libxl_conf.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 05d671bae7..458dfc2399 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -158,6 +158,27 @@ libxlMakeDomCreateInfo(libxl_ctx *ctx, c_info->type = LIBXL_DOMAIN_TYPE_PV; } +#ifdef LIBXL_HAVE_CREATEINFO_PASSTHROUGH + if (def->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) { + switch ((virTristateSwitch) def->xen_features[VIR_DOMAIN_XEN_PASSTHROUGH]) { + case VIR_TRISTATE_SWITCH_ON: + if (def->xen_passthrough_mode == VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SYNC_PT) + c_info->passthrough = LIBXL_PASSTHROUGH_SYNC_PT; + else if (def->xen_passthrough_mode == VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SHARE_PT) + c_info->passthrough = LIBXL_PASSTHROUGH_SHARE_PT; + else + c_info->passthrough = LIBXL_PASSTHROUGH_ENABLED; + break; + case VIR_TRISTATE_SWITCH_OFF: + c_info->passthrough = LIBXL_PASSTHROUGH_DISABLED; + break; + case VIR_TRISTATE_SWITCH_ABSENT: + case VIR_TRISTATE_SWITCH_LAST: + break; + } + } +#endif + c_info->name = g_strdup(def->name); if (def->nseclabels && -- 2.26.0

Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/libxl/xen_common.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c index bbb9739e01..87c66becaf 100644 --- a/src/libxl/xen_common.c +++ b/src/libxl/xen_common.c @@ -493,15 +493,12 @@ xenParsePCIList(virConfPtr conf, virDomainDefPtr def) static int -xenParseCPUFeatures(virConfPtr conf, - virDomainDefPtr def, - virDomainXMLOptionPtr xmlopt) +xenParseCPU(virConfPtr conf, + virDomainDefPtr def, + virDomainXMLOptionPtr xmlopt) { unsigned long count = 0; g_autofree char *cpus = NULL; - g_autofree char *tsc_mode = NULL; - int val = 0; - virDomainTimerDefPtr timer; if (xenConfigGetULong(conf, "vcpus", &count, 1) < 0) return -1; @@ -526,6 +523,17 @@ xenParseCPUFeatures(virConfPtr conf, if (cpus && (virBitmapParse(cpus, &def->cpumask, 4096) < 0)) return -1; + return 0; +} + + +static int +xenParseHypervisorFeatures(virConfPtr conf, virDomainDefPtr def) +{ + g_autofree char *tsc_mode = NULL; + virDomainTimerDefPtr timer; + int val = 0; + if (xenConfigGetString(conf, "tsc_mode", &tsc_mode, NULL) < 0) return -1; @@ -552,27 +560,26 @@ xenParseCPUFeatures(virConfPtr conf, if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { if (xenConfigGetBool(conf, "pae", &val, 1) < 0) return -1; - else if (val) def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_TRISTATE_SWITCH_ON; + if (xenConfigGetBool(conf, "acpi", &val, 1) < 0) return -1; - else if (val) def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON; + if (xenConfigGetBool(conf, "apic", &val, 1) < 0) return -1; - else if (val) def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_TRISTATE_SWITCH_ON; + if (xenConfigGetBool(conf, "hap", &val, 1) < 0) return -1; - else if (!val) def->features[VIR_DOMAIN_FEATURE_HAP] = VIR_TRISTATE_SWITCH_OFF; + if (xenConfigGetBool(conf, "viridian", &val, 0) < 0) return -1; - else if (val) def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] = VIR_TRISTATE_SWITCH_ON; @@ -1483,7 +1490,10 @@ xenParseConfigCommon(virConfPtr conf, if (xenParseEventsActions(conf, def) < 0) return -1; - if (xenParseCPUFeatures(conf, def, xmlopt) < 0) + if (xenParseCPU(conf, def, xmlopt) < 0) + return -1; + + if (xenParseHypervisorFeatures(conf, def) < 0) return -1; if (xenParseTimeOffset(conf, def) < 0) @@ -2115,7 +2125,7 @@ xenFormatCPUAllocation(virConfPtr conf, virDomainDefPtr def) static int -xenFormatCPUFeatures(virConfPtr conf, virDomainDefPtr def) +xenFormatHypervisorFeatures(virConfPtr conf, virDomainDefPtr def) { size_t i; bool hvm = !!(def->os.type == VIR_DOMAIN_OSTYPE_HVM); @@ -2423,7 +2433,7 @@ xenFormatConfigCommon(virConfPtr conf, if (xenFormatCPUAllocation(conf, def) < 0) return -1; - if (xenFormatCPUFeatures(conf, def) < 0) + if (xenFormatHypervisorFeatures(conf, def) < 0) return -1; if (xenFormatTimeOffset(conf, def) < 0) -- 2.26.0

Add support for xl.cfg(5) 'passthrough' option in the domXML-to-xenconfig configuration converter. Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/libvirt_private.syms | 2 ++ src/libxl/xen_common.c | 50 +++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ec367653d5..54a0378f36 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -649,6 +649,8 @@ virDomainWatchdogActionTypeToString; virDomainWatchdogDefFree; virDomainWatchdogModelTypeFromString; virDomainWatchdogModelTypeToString; +virDomainXenPassthroughModeTypeFromString; +virDomainXenPassthroughModeTypeToString; virDomainXMLOptionGetNamespace; virDomainXMLOptionGetSaveCookie; virDomainXMLOptionNew; diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c index 87c66becaf..5c37e431eb 100644 --- a/src/libxl/xen_common.c +++ b/src/libxl/xen_common.c @@ -530,14 +530,14 @@ xenParseCPU(virConfPtr conf, static int xenParseHypervisorFeatures(virConfPtr conf, virDomainDefPtr def) { - g_autofree char *tsc_mode = NULL; + g_autofree char *strval = NULL; virDomainTimerDefPtr timer; int val = 0; - if (xenConfigGetString(conf, "tsc_mode", &tsc_mode, NULL) < 0) + if (xenConfigGetString(conf, "tsc_mode", &strval, NULL) < 0) return -1; - if (tsc_mode) { + if (strval) { if (VIR_EXPAND_N(def->clock.timers, def->clock.ntimers, 1) < 0 || VIR_ALLOC(timer) < 0) return -1; @@ -547,16 +547,40 @@ xenParseHypervisorFeatures(virConfPtr conf, virDomainDefPtr def) timer->tickpolicy = -1; timer->mode = VIR_DOMAIN_TIMER_MODE_AUTO; timer->track = -1; - if (STREQ_NULLABLE(tsc_mode, "always_emulate")) + if (STREQ_NULLABLE(strval, "always_emulate")) timer->mode = VIR_DOMAIN_TIMER_MODE_EMULATE; - else if (STREQ_NULLABLE(tsc_mode, "native")) + else if (STREQ_NULLABLE(strval, "native")) timer->mode = VIR_DOMAIN_TIMER_MODE_NATIVE; - else if (STREQ_NULLABLE(tsc_mode, "native_paravirt")) + else if (STREQ_NULLABLE(strval, "native_paravirt")) timer->mode = VIR_DOMAIN_TIMER_MODE_PARAVIRT; def->clock.timers[def->clock.ntimers - 1] = timer; } + if (xenConfigGetString(conf, "passthrough", &strval, NULL) < 0) + return -1; + + if (strval) { + if (STREQ(strval, "disabled")) { + def->features[VIR_DOMAIN_FEATURE_XEN] = VIR_TRISTATE_SWITCH_OFF; + def->xen_features[VIR_DOMAIN_XEN_PASSTHROUGH] = VIR_TRISTATE_SWITCH_OFF; + } else if (STREQ(strval, "enabled")) { + def->features[VIR_DOMAIN_FEATURE_XEN] = VIR_TRISTATE_SWITCH_ON; + def->xen_features[VIR_DOMAIN_XEN_PASSTHROUGH] = VIR_TRISTATE_SWITCH_ON; + } else if (STREQ(strval, "sync_pt")) { + def->features[VIR_DOMAIN_FEATURE_XEN] = VIR_TRISTATE_SWITCH_ON; + def->xen_features[VIR_DOMAIN_XEN_PASSTHROUGH] = VIR_TRISTATE_SWITCH_ON; + def->xen_passthrough_mode = VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SYNC_PT; + } else if (STREQ(strval, "share_pt")) { + def->features[VIR_DOMAIN_FEATURE_XEN] = VIR_TRISTATE_SWITCH_ON; + def->xen_features[VIR_DOMAIN_XEN_PASSTHROUGH] = VIR_TRISTATE_SWITCH_ON; + def->xen_passthrough_mode = VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SHARE_PT; + } else { + virReportError(VIR_ERR_CONF_SYNTAX, + _("Invalid passthrough mode %s"), strval); + } + } + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { if (xenConfigGetBool(conf, "pae", &val, 1) < 0) return -1; @@ -2163,6 +2187,20 @@ xenFormatHypervisorFeatures(virConfPtr conf, virDomainDefPtr def) } } + if (def->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) { + if (def->xen_features[VIR_DOMAIN_XEN_PASSTHROUGH] == VIR_TRISTATE_SWITCH_ON) { + if (def->xen_passthrough_mode == VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SYNC_PT || + def->xen_passthrough_mode == VIR_DOMAIN_XEN_PASSTHROUGH_MODE_SHARE_PT) { + if (xenConfigSetString(conf, "passthrough", + virDomainXenPassthroughModeTypeToString(def->xen_passthrough_mode)) < 0) + return -1; + } else { + if (xenConfigSetString(conf, "passthrough", "enabled") < 0) + return -1; + } + } + } + for (i = 0; i < def->clock.ntimers; i++) { switch ((virDomainTimerNameType)def->clock.timers[i]->name) { case VIR_DOMAIN_TIMER_NAME_TSC: -- 2.26.0

Add a new test to check the 'mode' attribute of the passthrough element and augment an existing, related test to check enablement of the passthrough element only. Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- .../test-fullvirt-hypervisor-features.cfg | 26 ++++++++++ .../test-fullvirt-hypervisor-features.xml | 50 +++++++++++++++++++ .../xlconfigdata/test-paravirt-e820_host.cfg | 1 + .../xlconfigdata/test-paravirt-e820_host.xml | 1 + tests/xlconfigtest.c | 3 ++ 5 files changed, 81 insertions(+) diff --git a/tests/xlconfigdata/test-fullvirt-hypervisor-features.cfg b/tests/xlconfigdata/test-fullvirt-hypervisor-features.cfg new file mode 100644 index 0000000000..88f018c823 --- /dev/null +++ b/tests/xlconfigdata/test-fullvirt-hypervisor-features.cfg @@ -0,0 +1,26 @@ +name = "XenGuest2" +uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809" +maxmem = 579 +memory = 394 +vcpus = 1 +pae = 1 +acpi = 1 +apic = 1 +viridian = 0 +passthrough = "share_pt" +rtc_timeoffset = 0 +localtime = 0 +on_poweroff = "destroy" +on_reboot = "restart" +on_crash = "restart" +device_model = "/usr/lib/xen/bin/qemu-system-i386" +sdl = 0 +vnc = 1 +vncunused = 1 +vnclisten = "127.0.0.1" +vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000" ] +parallel = "none" +serial = "none" +builder = "hvm" +boot = "c" +disk = [ "format=raw,vdev=hda,access=rw,backendtype=phy,target=/dev/HostVG/XenGuest2" ] diff --git a/tests/xlconfigdata/test-fullvirt-hypervisor-features.xml b/tests/xlconfigdata/test-fullvirt-hypervisor-features.xml new file mode 100644 index 0000000000..c36290bb6a --- /dev/null +++ b/tests/xlconfigdata/test-fullvirt-hypervisor-features.xml @@ -0,0 +1,50 @@ +<domain type='xen'> + <name>XenGuest2</name> + <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>592896</memory> + <currentMemory unit='KiB'>403456</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='xenfv'>hvm</type> + <loader type='rom'>/usr/lib/xen/boot/hvmloader</loader> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + <xen> + <passthrough state='on' mode='share_pt'/> + </xen> + </features> + <clock offset='variable' adjustment='0' basis='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/lib/xen/bin/qemu-system-i386</emulator> + <disk type='block' device='disk'> + <driver name='phy' type='raw'/> + <source dev='/dev/HostVG/XenGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='xenbus' index='0'/> + <controller type='ide' index='0'/> + <interface type='bridge'> + <mac address='00:16:3e:66:92:9c'/> + <source bridge='xenbr1'/> + <script path='vif-bridge'/> + <model type='e1000'/> + </interface> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1'> + <listen type='address' address='127.0.0.1'/> + </graphics> + <video> + <model type='cirrus' vram='8192' heads='1' primary='yes'/> + </video> + <memballoon model='xen'/> + </devices> +</domain> diff --git a/tests/xlconfigdata/test-paravirt-e820_host.cfg b/tests/xlconfigdata/test-paravirt-e820_host.cfg index b9e5a482a4..ad6cb8420b 100644 --- a/tests/xlconfigdata/test-paravirt-e820_host.cfg +++ b/tests/xlconfigdata/test-paravirt-e820_host.cfg @@ -4,6 +4,7 @@ maxmem = 512 memory = 512 vcpus = 4 e820_host = 1 +passthrough = "enabled" localtime = 0 on_poweroff = "preserve" on_reboot = "restart" diff --git a/tests/xlconfigdata/test-paravirt-e820_host.xml b/tests/xlconfigdata/test-paravirt-e820_host.xml index 955a780ffa..d3bfb156eb 100644 --- a/tests/xlconfigdata/test-paravirt-e820_host.xml +++ b/tests/xlconfigdata/test-paravirt-e820_host.xml @@ -11,6 +11,7 @@ <features> <xen> <e820_host state='on'/> + <passthrough state='on'/> </xen> </features> <clock offset='utc' adjustment='reset'/> diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c index 8ea250347b..b2e045dfa5 100644 --- a/tests/xlconfigtest.c +++ b/tests/xlconfigtest.c @@ -301,6 +301,9 @@ mymain(void) DO_TEST("usb"); DO_TEST("usbctrl"); DO_TEST("paravirt-e820_host"); +#ifdef LIBXL_HAVE_CREATEINFO_PASSTHROUGH + DO_TEST("fullvirt-hypervisor-features"); +#endif testXLFreeDriver(driver); -- 2.26.0

On 4/18/20 12:29 AM, Jim Fehlig wrote:
Hi All,
Note: This series is based on Marek's patches adding support for e820_host
https://www.redhat.com/archives/libvir-list/2020-April/msg00633.html
which I've ACK'ed, but am waiting to commit until this related setting is hashed out.
This series adds support for Xen's xl.cfg(5) 'passthrough' setting. Starting with xen 4.13 this setting must be enabled in order to assign PCI passthrough devices to a guest. libxl will enable it automatically if the guest config has PCI devices at creation time, but otherwise 'passthrough' must be enabled to hotplug PCI devices.
The passthrough setting is mapped to a xen hypervisor feature of the same name. Xen hypervisor features were recently added by the series mentioned above.
Jim Fehlig (5): conf: add xen hypervisor feature 'passthrough' libxl: make use of passthrough hypervisor feature libxl: refactor cpu and hypervisor feature parser/formatter xenconfig: Add support for 'passthrough' hypervisor feature tests: check conversion of passthrough hypervisor feature
docs/formatdomain.html.in | 7 ++ docs/schemas/domaincommon.rng | 12 ++ src/conf/domain_conf.c | 115 ++++++++++++++---- src/conf/domain_conf.h | 11 ++ src/libvirt_private.syms | 2 + src/libxl/libxl_conf.c | 21 ++++ src/libxl/xen_common.c | 86 ++++++++++--- .../test-fullvirt-hypervisor-features.cfg | 26 ++++ .../test-fullvirt-hypervisor-features.xml | 50 ++++++++ .../xlconfigdata/test-paravirt-e820_host.cfg | 1 + .../xlconfigdata/test-paravirt-e820_host.xml | 1 + tests/xlconfigtest.c | 3 + 12 files changed, 290 insertions(+), 45 deletions(-) create mode 100644 tests/xlconfigdata/test-fullvirt-hypervisor-features.cfg create mode 100644 tests/xlconfigdata/test-fullvirt-hypervisor-features.xml
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal

On Fri, Apr 17, 2020 at 04:29:34PM -0600, Jim Fehlig wrote:
Hi All,
Note: This series is based on Marek's patches adding support for e820_host
https://www.redhat.com/archives/libvir-list/2020-April/msg00633.html
which I've ACK'ed, but am waiting to commit until this related setting is hashed out.
This series adds support for Xen's xl.cfg(5) 'passthrough' setting. Starting with xen 4.13 this setting must be enabled in order to assign PCI passthrough devices to a guest. libxl will enable it automatically if the guest config has PCI devices at creation time, but otherwise 'passthrough' must be enabled to hotplug PCI devices.
The passthrough setting is mapped to a xen hypervisor feature of the same name. Xen hypervisor features were recently added by the series mentioned above.
I'm wondering how does it relate to other drivers/hypervisors. Is there any other that requires some option to be enabled to enable PCI hot plugging? If yes, I'd try to model this one similar to existing cases. Otherwise modeling it as a Xen feature would make sense. -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?

On 4/24/20 4:57 AM, Marek Marczykowski-Górecki wrote:
On Fri, Apr 17, 2020 at 04:29:34PM -0600, Jim Fehlig wrote:
Hi All,
Note: This series is based on Marek's patches adding support for e820_host
https://www.redhat.com/archives/libvir-list/2020-April/msg00633.html
which I've ACK'ed, but am waiting to commit until this related setting is hashed out.
This series adds support for Xen's xl.cfg(5) 'passthrough' setting. Starting with xen 4.13 this setting must be enabled in order to assign PCI passthrough devices to a guest. libxl will enable it automatically if the guest config has PCI devices at creation time, but otherwise 'passthrough' must be enabled to hotplug PCI devices.
The passthrough setting is mapped to a xen hypervisor feature of the same name. Xen hypervisor features were recently added by the series mentioned above.
I'm wondering how does it relate to other drivers/hypervisors. Is there any other that requires some option to be enabled to enable PCI hot plugging?
I'm not aware of any, but may have overlooked something. I relayed the question on IRC with no answer thus far.
If yes, I'd try to model this one similar to existing cases.
Definitely.
Otherwise modeling it as a Xen feature would make sense.
That is what I pushed, although we have about a week to change our minds :-). Regards, Jim
participants (3)
-
Jim Fehlig
-
Marek Marczykowski-Górecki
-
Michal Privoznik