Since 8.0 version, qemu introduced a new device of 'vhost-vdpa-device-pci' that does not differentiate specific virtio devices, which called generic vDPA device. The generic vDPA solution avoids the need for maintaining a large amount of device emulation code, reducing maintenance costs.. the device configured as follows: <gvdpa> <source dev='/dev/vhost-vdpa-0'/> </gvdpa> Signed-off-by: Yunfeng Qi <yunfeng.qi@xxxxxxxxxxxxxxx> --- docs/formatdomain.rst | 17 +++ src/ch/ch_domain.c | 1 + src/conf/domain_conf.c | 106 ++++++++++++++++++ src/conf/domain_conf.h | 12 ++ src/conf/domain_postparse.c | 1 + src/conf/domain_validate.c | 11 ++ src/conf/schemas/domaincommon.rng | 23 ++++ src/conf/virconftypes.h | 2 + src/hyperv/hyperv_driver.c | 1 + src/libxl/libxl_driver.c | 6 + src/lxc/lxc_driver.c | 6 + src/qemu/qemu_alias.c | 21 ++++ src/qemu/qemu_cgroup.c | 6 + src/qemu/qemu_command.c | 55 +++++++++ src/qemu/qemu_domain.c | 3 + src/qemu/qemu_domain_address.c | 13 +++ src/qemu/qemu_driver.c | 3 + src/qemu/qemu_hotplug.c | 5 + src/qemu/qemu_validate.c | 12 ++ src/vz/vz_sdk.c | 3 + .../generic-vdpa.x86_64-latest.args | 34 ++++++ .../generic-vdpa.x86_64-latest.xml | 1 + tests/qemuxmlconfdata/generic-vdpa.xml | 43 +++++++ tests/qemuxmlconftest.c | 1 + 24 files changed, 386 insertions(+) create mode 100644 tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.args create mode 120000 tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/generic-vdpa.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 2adc2ff..182987b 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -8622,6 +8622,23 @@ The optional attribute ``backend`` is required if the ``type`` is ``qemu``, the ... +GVdpa +~~~~~~ + +A generic vdpa device. +The attribute ``dev`` is required and specifies the path of the generic vdpa device. + +:: + + ... + <devices> + <gvdpa> + <source dev='/dev/vhost-vdpa-0'/> + </gvdpa> + </devices> + ... + + Security label -------------- diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c index 8e3e205..f9fbad6 100644 --- a/src/ch/ch_domain.c +++ b/src/ch/ch_domain.c @@ -180,6 +180,7 @@ chValidateDomainDeviceDef(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Cloud-Hypervisor doesn't support '%1$s' device"), virDomainDeviceTypeToString(dev->type)); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 770b5fb..100d112 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -336,6 +336,7 @@ VIR_ENUM_IMPL(virDomainDevice, "vsock", "audio", "crypto", + "gvdpa" ); VIR_ENUM_IMPL(virDomainDiskDevice, @@ -3627,6 +3628,9 @@ void virDomainDeviceDefFree(virDomainDeviceDef *def) case VIR_DOMAIN_DEVICE_CRYPTO: virDomainCryptoDefFree(def->data.crypto); break; + case VIR_DOMAIN_DEVICE_GVDPA: + virDomainGVdpaDefFree(def->data.gvdpa); + break; case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_NONE: break; @@ -3984,6 +3988,10 @@ void virDomainDefFree(virDomainDef *def) virDomainCryptoDefFree(def->cryptos[i]); g_free(def->cryptos); + for (i = 0; i < def->ngvdpas; i++) + virDomainGVdpaDefFree(def->gvdpas[i]); + g_free(def->gvdpas); + virDomainIOMMUDefFree(def->iommu); g_free(def->idmap.uidmap); @@ -4543,6 +4551,8 @@ virDomainDeviceGetInfo(const virDomainDeviceDef *device) return &device->data.vsock->info; case VIR_DOMAIN_DEVICE_CRYPTO: return &device->data.crypto->info; + case VIR_DOMAIN_DEVICE_GVDPA: + return &device->data.gvdpa->info; /* The following devices do not contain virDomainDeviceInfo */ case VIR_DOMAIN_DEVICE_LEASE: @@ -4648,6 +4658,9 @@ virDomainDeviceSetData(virDomainDeviceDef *device, case VIR_DOMAIN_DEVICE_CRYPTO: device->data.crypto = devicedata; break; + case VIR_DOMAIN_DEVICE_GVDPA: + device->data.gvdpa = devicedata; + break; case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; @@ -4866,6 +4879,13 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def, return rc; } + device.type = VIR_DOMAIN_DEVICE_GVDPA; + for (i = 0; i < def->ngvdpas; i++) { + device.data.gvdpa = def->gvdpas[i]; + if ((rc = cb(def, &device, &def->gvdpas[i]->info, opaque)) != 0) + return rc; + } + /* If the flag below is set, make sure @cb can handle @info being NULL */ if (iteratorFlags & DOMAIN_DEVICE_ITERATE_MISSING_INFO) { device.type = VIR_DOMAIN_DEVICE_GRAPHICS; @@ -4925,6 +4945,7 @@ virDomainDeviceInfoIterateFlags(virDomainDef *def, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: break; } #endif @@ -13892,6 +13913,41 @@ virDomainCryptoDefParseXML(virDomainXMLOption *xmlopt, return g_steal_pointer(&def); } +static virDomainGVdpaDef * +virDomainGVdpaDefParseXML(virDomainXMLOption *xmlopt, + xmlNodePtr node, + xmlXPathContextPtr ctxt, + unsigned int flags) +{ + g_autoptr(virDomainGVdpaDef) def = NULL; + int nsources; + g_autofree xmlNodePtr *sources = NULL; + VIR_XPATH_NODE_AUTORESTORE(ctxt) + + def = g_new0(virDomainGVdpaDef, 1); + ctxt->node = node; + + if ((nsources = virXPathNodeSet("./source", ctxt, &sources)) < 0) + return NULL; + + if (nsources != 1) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only one gvdpa source is supported")); + return NULL; + } + + if (!(def->dev = virXMLPropString(sources[0], "dev"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing dev element")); + return NULL; + } + + if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, flags | VIR_DOMAIN_DEF_PARSE_ALLOW_BOOT) < 0) + return NULL; + + return g_steal_pointer(&def); +} + static int virDomainDeviceDefParseType(const char *typestr, @@ -14072,6 +14128,11 @@ virDomainDeviceDefParse(const char *xmlStr, flags))) return NULL; break; + case VIR_DOMAIN_DEVICE_GVDPA: + if (!(dev->data.gvdpa = virDomainGVdpaDefParseXML(xmlopt, node, ctxt, + flags))) + return NULL; + break; case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; @@ -19230,6 +19291,21 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt, } VIR_FREE(nodes); + /* Parse the gvdpa devices */ + if ((n = virXPathNodeSet("./devices/gvdpa", ctxt, &nodes)) < 0) + return NULL; + if (n) + def->gvdpas = g_new0(virDomainGVdpaDef *, n); + for (i = 0; i < n; i++) { + virDomainGVdpaDef *gvdpa = virDomainGVdpaDefParseXML(xmlopt, nodes[i], + ctxt, flags); + if (!gvdpa) + return NULL; + + def->gvdpas[def->ngvdpas++] = gvdpa; + } + VIR_FREE(nodes); + /* Parse the TPM devices */ if ((n = virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0) return NULL; @@ -21788,6 +21864,7 @@ virDomainDefCheckABIStabilityFlags(virDomainDef *src, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: break; } #endif @@ -25334,6 +25411,22 @@ virDomainCryptoDefFormat(virBuffer *buf, virXMLFormatElement(buf, "crypto", &attrBuf, &childBuf); } +static void +virDomainGVdpaDefFormat(virBuffer *buf, + virDomainGVdpaDef *def, + unsigned int flags) +{ + virBufferAddLit(buf, "<gvdpa>\n"); + + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<source dev='%s'/>\n", def->dev); + virDomainDeviceInfoFormat(buf, &def->info, flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</gvdpa>\n"); +} + + void virDomainCryptoDefFree(virDomainCryptoDef *def) { @@ -25345,6 +25438,16 @@ virDomainCryptoDefFree(virDomainCryptoDef *def) g_free(def); } +void +virDomainGVdpaDefFree(virDomainGVdpaDef *def) +{ + if (!def) + return; + + virDomainDeviceInfoClear(&def->info); + g_free(def->dev); + g_free(def); +} static int virDomainMemorySourceDefFormat(virBuffer *buf, @@ -28139,6 +28242,9 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def, for (n = 0; n < def->ncryptos; n++) { virDomainCryptoDefFormat(buf, def->cryptos[n], flags); } + for (n = 0; n < def->ngvdpas; n++) { + virDomainGVdpaDefFormat(buf, def->gvdpas[n], flags); + } if (def->iommu) virDomainIOMMUDefFormat(buf, def->iommu); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7625193..a0c94af 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -87,6 +87,7 @@ typedef enum { VIR_DOMAIN_DEVICE_VSOCK, VIR_DOMAIN_DEVICE_AUDIO, VIR_DOMAIN_DEVICE_CRYPTO, + VIR_DOMAIN_DEVICE_GVDPA, VIR_DOMAIN_DEVICE_LAST } virDomainDeviceType; @@ -120,6 +121,7 @@ struct _virDomainDeviceDef { virDomainVsockDef *vsock; virDomainAudioDef *audio; virDomainCryptoDef *crypto; + virDomainGVdpaDef *gvdpa; } data; }; @@ -2943,6 +2945,11 @@ struct _virDomainCryptoDef { virDomainVirtioOptions *virtio; }; +struct _virDomainGVdpaDef { + char *dev; + virDomainDeviceInfo info; +}; + struct _virDomainVirtioOptions { virTristateSwitch iommu; virTristateSwitch ats; @@ -3112,6 +3119,9 @@ struct _virDomainDef { size_t ncryptos; virDomainCryptoDef **cryptos; + size_t ngvdpas; + virDomainGVdpaDef **gvdpas; + size_t nwatchdogs; virDomainWatchdogDef **watchdogs; @@ -3569,6 +3579,8 @@ void virDomainVsockDefFree(virDomainVsockDef *vsock); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVsockDef, virDomainVsockDefFree); void virDomainCryptoDefFree(virDomainCryptoDef *def); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainCryptoDef, virDomainCryptoDefFree); +void virDomainGVdpaDefFree(virDomainGVdpaDef *def); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainGVdpaDef, virDomainGVdpaDefFree); void virDomainNetTeamingInfoFree(virDomainNetTeamingInfo *teaming); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainNetTeamingInfo, virDomainNetTeamingInfoFree); void virDomainNetPortForwardFree(virDomainNetPortForward *pf); diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c index cafa2d2..5a568e8 100644 --- a/src/conf/domain_postparse.c +++ b/src/conf/domain_postparse.c @@ -746,6 +746,7 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: ret = 0; break; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index faa7659..c6729e4 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -2576,6 +2576,14 @@ virDomainCryptoDefValidate(const virDomainCryptoDef *crypto) return 0; } +static int +virDomainGVdpaDefValidate(const virDomainGVdpaDef *gvdpa) +{ + if (!gvdpa->dev) + return -1; + + return 0; +} static int virDomainInputDefValidate(const virDomainInputDef *input, @@ -3058,6 +3066,9 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_CRYPTO: return virDomainCryptoDefValidate(dev->data.crypto); + case VIR_DOMAIN_DEVICE_GVDPA: + return virDomainGVdpaDefValidate(dev->data.gvdpa); + case VIR_DOMAIN_DEVICE_INPUT: return virDomainInputDefValidate(dev->data.input, def); diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index c992956..c7c7314 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6609,6 +6609,7 @@ <ref name="shmem"/> <ref name="memorydev"/> <ref name="crypto"/> + <ref name="gvdpa"/> </choice> </zeroOrMore> <zeroOrMore> @@ -7457,6 +7458,28 @@ </define> + <define name="gvdpa"> + <element name="gvdpa"> + <interleave> + <ref name="gvdpa-source"/> + <optional> + <ref name="alias"/> + </optional> + <optional> + <ref name="address"/> + </optional> + </interleave> + </element> + </define> + + <define name="gvdpa-source"> + <element name="source"> + <attribute name="dev"> + <text/> + </attribute> + </element> + </define> + <define name="virtioOptions"> <optional> <attribute name="iommu"> diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index 0779bc2..924138a 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -256,6 +256,8 @@ typedef struct _virDomainVsockDef virDomainVsockDef; typedef struct _virDomainCryptoDef virDomainCryptoDef; +typedef struct _virDomainGVdpaDef virDomainGVdpaDef; + typedef struct _virDomainWatchdogDef virDomainWatchdogDef; typedef struct _virDomainXMLOption virDomainXMLOption; diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 414274f..c7e5cce 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -3132,6 +3132,7 @@ hypervDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_INTERNAL_ERROR, _("Attaching devices of type %1$d is not implemented"), dev->type); return -1; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index e42a3dc..1664c33 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3505,6 +3505,7 @@ libxlDomainAttachDeviceLive(libxlDriverPrivate *driver, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("device type '%1$s' cannot be attached"), virDomainDeviceTypeToString(dev->type)); @@ -3613,6 +3614,7 @@ libxlDomainAttachDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev) case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent attach of device is not supported")); return -1; @@ -3981,6 +3983,7 @@ libxlDomainDetachDeviceLive(libxlDriverPrivate *driver, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("device type '%1$s' cannot be detached"), virDomainDeviceTypeToString(dev->type)); @@ -4071,6 +4074,7 @@ libxlDomainDetachDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev) case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent detach of device is not supported")); return -1; @@ -4133,6 +4137,7 @@ libxlDomainUpdateDeviceLive(virDomainObj *vm, virDomainDeviceDef *dev) case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("device type '%1$s' cannot be updated"), virDomainDeviceTypeToString(dev->type)); @@ -4195,6 +4200,7 @@ libxlDomainUpdateDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev) case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent update of device is not supported")); return -1; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 39992bd..7d11529 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -3054,6 +3054,7 @@ lxcDomainAttachDeviceConfig(virDomainDef *vmdef, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent attach of device is not supported")); break; @@ -3119,6 +3120,7 @@ lxcDomainUpdateDeviceConfig(virDomainDef *vmdef, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent update of device is not supported")); break; @@ -3199,6 +3201,7 @@ lxcDomainDetachDeviceConfig(virDomainDef *vmdef, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_AUDIO: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent detach of device is not supported")); @@ -3301,6 +3304,7 @@ lxcDomainAttachDeviceMknodHelper(pid_t pid G_GNUC_UNUSED, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected device type %1$d"), data->def->type); @@ -3972,6 +3976,7 @@ lxcDomainAttachDeviceLive(virLXCDriver *driver, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("device type '%1$s' cannot be attached"), virDomainDeviceTypeToString(dev->type)); @@ -4396,6 +4401,7 @@ lxcDomainDetachDeviceLive(virLXCDriver *driver, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("device type '%1$s' cannot be detached"), virDomainDeviceTypeToString(dev->type)); diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index 872d940..518abd3 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -657,6 +657,24 @@ qemuAssignDeviceCryptoAlias(virDomainDef *def, crypto->info.alias = g_strdup_printf("crypto%d", maxidx); } +static void +qemuAssignDeviceGVdpaAlias(virDomainDef *def, + virDomainGVdpaDef *gvdpa) +{ + size_t i; + int maxidx = 0; + int idx; + + if (gvdpa->info.alias) + return; + + for (i = 0; i < def->ngvdpas; i++) { + if ((idx = qemuDomainDeviceAliasIndex(&def->gvdpas[i]->info, "gvdpa")) >= maxidx) + maxidx = idx + 1; + } + + gvdpa->info.alias = g_strdup_printf("gvdpa%d", maxidx); +} int qemuAssignDeviceAliases(virDomainDef *def) @@ -747,6 +765,9 @@ qemuAssignDeviceAliases(virDomainDef *def) for (i = 0; i < def->ncryptos; i++) { qemuAssignDeviceCryptoAlias(def, def->cryptos[i]); } + for (i = 0; i < def->ngvdpas; i++) { + qemuAssignDeviceGVdpaAlias(def, def->gvdpas[i]); + } return 0; } diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 5a5ba76..1206359 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -845,6 +845,12 @@ qemuSetupDevicesCgroup(virDomainObj *vm) return -1; } + for (i = 0; i < vm->def->ngvdpas; i++) { + if (qemuCgroupAllowDevicePath(vm, vm->def->gvdpas[i]->dev, + VIR_CGROUP_DEVICE_RW, false) < 0) + return -1; + } + if (vm->def->sec && vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV && qemuSetupSEVCgroup(vm) < 0) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 2bb1b6a..faf96f9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -969,6 +969,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_LAST: + case VIR_DOMAIN_DEVICE_GVDPA: default: break; } @@ -10254,6 +10255,57 @@ qemuBuildCryptoCommandLine(virCommand *cmd, return 0; } +static virJSONValue * +qemuBuildGVdpaDevProps(const virDomainDef *def, + virDomainGVdpaDef *dev) +{ + g_autoptr(virJSONValue) props = NULL; + + if (virJSONValueObjectAdd(&props, + "s:driver", "vhost-vdpa-device-pci", + "s:vhostdev", dev->dev, + "s:id", dev->info.alias, + "p:bootindex", dev->info.effectiveBootIndex, + NULL) < 0) + return NULL; + + if (qemuBuildDeviceAddressProps(props, def, &dev->info) < 0) + return NULL; + + return g_steal_pointer(&props); +} + +static int +qemuBuildGVdpaCommandLine(virCommand *cmd, + const virDomainDef *def, + virQEMUCaps *qemuCaps) +{ + size_t i; + + for (i = 0; i < def->ngvdpas; i++) { + virDomainGVdpaDef *gvdpa = def->gvdpas[i]; + g_autoptr(virJSONValue) devprops = NULL; + + if (!gvdpa->info.alias) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("GVdpa device is missing alias")); + return -1; + } + + /* add the device */ + if (qemuCommandAddExtDevice(cmd, &gvdpa->info, def, qemuCaps) < 0) + return -1; + + if (!(devprops = qemuBuildGVdpaDevProps(def, gvdpa))) + return -1; + + if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, def, qemuCaps) < 0) + return -1; + } + + return 0; +} + static int qemuBuildAsyncTeardownCommandLine(virCommand *cmd, @@ -10628,6 +10680,9 @@ qemuBuildCommandLine(virDomainObj *vm, if (qemuBuildCryptoCommandLine(cmd, def, qemuCaps) < 0) return NULL; + if (qemuBuildGVdpaCommandLine(cmd, def, qemuCaps) < 0) + return NULL; + if (qemuBuildAsyncTeardownCommandLine(cmd, def, qemuCaps) < 0) return NULL; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index bc6cf13..132b479 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6324,6 +6324,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: ret = 0; break; @@ -10301,6 +10302,7 @@ qemuDomainPrepareChardevSourceOne(virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: break; } @@ -12232,6 +12234,7 @@ qemuDomainDeviceBackendChardevForeachOne(virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: /* no chardev backend */ break; } diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index cc3bc76..5db2dfa 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -464,6 +464,7 @@ qemuDomainDeviceSupportZPCI(virDomainDeviceDef *device) case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: break; case VIR_DOMAIN_DEVICE_NONE: @@ -978,6 +979,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, } break; + case VIR_DOMAIN_DEVICE_GVDPA: + return pciFlags; + case VIR_DOMAIN_DEVICE_PANIC: switch ((virDomainPanicModel) dev->data.panic->model) { case VIR_DOMAIN_PANIC_MODEL_PVPANIC: @@ -2392,6 +2396,15 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, return -1; } + /* gvdpa */ + for (i = 0; i < def->ngvdpas; i++) { + if (!virDeviceInfoPCIAddressIsWanted(&def->gvdpas[i]->info)) + continue; + + if (qemuDomainPCIAddressReserveNextAddr(addrs, &def->gvdpas[i]->info) < 0) + return -1; + } + for (i = 0; i < def->npanics; i++) { virDomainPanicDef *panic = def->panics[i]; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d01f788..5e3ea85 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6859,6 +6859,7 @@ qemuDomainAttachDeviceConfig(virDomainDef *vmdef, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent attach of device '%1$s' is not supported"), @@ -7066,6 +7067,7 @@ qemuDomainDetachDeviceConfig(virDomainDef *vmdef, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent detach of device '%1$s' is not supported"), @@ -7191,6 +7193,7 @@ qemuDomainUpdateDeviceConfig(virDomainDef *vmdef, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent update of device '%1$s' is not supported"), diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index b9c5026..dc9caec 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3454,6 +3454,7 @@ qemuDomainAttachDeviceLive(virDomainObj *vm, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("live attach of device '%1$s' is not supported"), @@ -5281,6 +5282,7 @@ qemuDomainRemoveAuditDevice(virDomainObj *vm, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: /* libvirt doesn't yet support detaching these devices */ break; @@ -5385,6 +5387,7 @@ qemuDomainRemoveDevice(virQEMUDriver *driver, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("don't know how to remove a %1$s device"), @@ -6239,6 +6242,7 @@ qemuDomainDetachDeviceLive(virDomainObj *vm, case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("live detach of device '%1$s' is not supported"), @@ -7228,6 +7232,7 @@ qemuDomainUpdateDeviceLive(virDomainObj *vm, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("live update of device '%1$s' is not supported"), diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 6a73d02..964cf5b 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4577,6 +4577,15 @@ qemuValidateDomainDeviceDefCrypto(virDomainCryptoDef *crypto, return 0; } +static int +qemuValidateDomainDeviceDefGVdpa(virDomainGVdpaDef *gvdpa G_GNUC_UNUSED, + const virDomainDef *def G_GNUC_UNUSED, + virQEMUCaps *qemuCaps G_GNUC_UNUSED) +{ + if (qemuValidateDomainDefVhostUserRequireSharedMemory(def, "generic-vdpa") < 0) + return -1; + return 0; +} static int qemuSoundCodecTypeToCaps(int type) @@ -5277,6 +5286,9 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_CRYPTO: return qemuValidateDomainDeviceDefCrypto(dev->data.crypto, def, qemuCaps); + case VIR_DOMAIN_DEVICE_GVDPA: + return qemuValidateDomainDeviceDefGVdpa(dev->data.gvdpa, def, qemuCaps); + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_NONE: diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index ce4586a..1c1064b 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -3534,6 +3534,7 @@ prlsdkAttachDevice(struct _vzDriver *driver, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("attaching device type '%1$s' is unsupported"), virDomainDeviceTypeToString(dev->type)); @@ -3624,6 +3625,7 @@ prlsdkDetachDevice(struct _vzDriver *driver G_GNUC_UNUSED, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("detaching device type '%1$s' is unsupported"), virDomainDeviceTypeToString(dev->type)); @@ -3704,6 +3706,7 @@ prlsdkUpdateDevice(struct _vzDriver *driver, case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: + case VIR_DOMAIN_DEVICE_GVDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("updating device type '%1$s' is unsupported"), virDomainDeviceTypeToString(dev->type)); diff --git a/tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.args b/tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.args new file mode 100644 index 0000000..7e904e2 --- /dev/null +++ b/tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-vm \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-vm/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-vm/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-vm/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=vm,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-vm/master-key.aes"}' \ +-machine pc-i440fx-8.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ +-accel tcg \ +-cpu qemu64,hypervisor=on,lahf-lm=on \ +-m size=2097152k \ +-object '{"qom-type":"memory-backend-file","id":"pc.ram","mem-path":"/var/lib/libvirt/qemu/ram/-1-vm/pc.ram","share":true,"x-use-canonical-path-for-ramblock-id":false,"size":2147483648}' \ +-overcommit mem-lock=off \ +-smp 2,sockets=2,cores=1,threads=1 \ +-uuid 85e32425-da0d-11ee-96fa-8430ce01b683 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-device '{"driver":"vhost-vdpa-device-pci","vhostdev":"/dev/vhost-vdpa-0","id":"gvdpa0","bootindex":1,"bus":"pci.0","addr":"0x9"}' \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.xml b/tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.xml new file mode 120000 index 0000000..ce074fe --- /dev/null +++ b/tests/qemuxmlconfdata/generic-vdpa.x86_64-latest.xml @@ -0,0 +1 @@ +generic-vdpa.xml \ No newline at end of file diff --git a/tests/qemuxmlconfdata/generic-vdpa.xml b/tests/qemuxmlconfdata/generic-vdpa.xml new file mode 100644 index 0000000..f2c6bae --- /dev/null +++ b/tests/qemuxmlconfdata/generic-vdpa.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>vm</name> + <uuid>85e32425-da0d-11ee-96fa-8430ce01b683</uuid> + <memory unit='KiB'>2097152</memory> + <currentMemory unit='KiB'>2097152</currentMemory> + <memoryBacking> + <access mode='shared'/> + </memoryBacking> + <vcpu placement='static'>2</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64' machine='pc-i440fx-8.0'>hvm</type> + </os> + <cpu mode='custom' match='exact' check='full'> + <model fallback='forbid'>qemu64</model> + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='lahf_lm'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </memballoon> + <gvdpa> + <source dev='/dev/vhost-vdpa-0'/> + <boot order='1'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </gvdpa> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 71b5913..357ab60 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2910,6 +2910,7 @@ mymain(void) DO_TEST_CAPS_VER("sgx-epc", "7.0.0"); DO_TEST_CAPS_LATEST("crypto-builtin"); + DO_TEST_CAPS_LATEST("generic-vdpa"); DO_TEST_CAPS_LATEST("async-teardown"); DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown", "s390x"); -- 2.25.1 _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx