:p
atchew
Login
The following is the xml of vdpa device: <devices> <hostdev mode='subsystem' type='vdpa'> <source dev='/dev/vhost-vdpa-0'/> </hostdev> </devices> And the command line passed to QEMU is as follows: -device {"driver":"vhost-vdpa-device-pci","vhostdev":"/dev/vhost-vdpa-0"} This solution is selected according to the previous discussion on the solution of supporting the vDPA device. For details, see the following: https://listman.redhat.com/archives/libvir-list/2023-March/239018.html Signed-off-by: libai <libai12@huawei.com> --- src/conf/domain_audit.c | 4 +++ src/conf/domain_conf.c | 47 +++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 6 +++++ src/conf/domain_validate.c | 1 + src/conf/virconftypes.h | 2 ++ src/qemu/qemu_command.c | 19 +++++++++++++ src/qemu/qemu_command.h | 3 +++ src/qemu/qemu_domain.c | 6 +++++ src/qemu/qemu_hotplug.c | 1 + src/qemu/qemu_migration.c | 2 ++ src/qemu/qemu_validate.c | 2 ++ src/security/security_dac.c | 2 ++ src/security/security_selinux.c | 2 ++ 13 files changed, 97 insertions(+) diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -XXX,XX +XXX,XX @@ virDomainAuditHostdev(virDomainObj *vm, virDomainHostdevDef *hostdev, virDomainHostdevSubsysSCSI *scsisrc = &hostdev->source.subsys.u.scsi; virDomainHostdevSubsysSCSIVHost *hostsrc = &hostdev->source.subsys.u.scsi_host; virDomainHostdevSubsysMediatedDev *mdevsrc = &hostdev->source.subsys.u.mdev; + virDomainHostdevSubsysVDPA *vdpasrc = &hostdev->source.subsys.u.vdpa; virUUIDFormat(vm->def->uuid, uuidstr); if (!(vmname = virAuditEncode("vm", vm->def->name))) { @@ -XXX,XX +XXX,XX @@ virDomainAuditHostdev(virDomainObj *vm, virDomainHostdevDef *hostdev, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: address = g_strdup(mdevsrc->uuidstr); break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + address = g_strdup(vdpasrc->devpath); + break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: default: VIR_WARN("Unexpected hostdev type while encoding audit message: %d", diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -XXX,XX +XXX,XX @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, "scsi", "scsi_host", "mdev", + "vdpa", ); VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefClear(virDomainHostdevDef *def) case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: g_clear_pointer(&def->source.subsys.u.pci.origstates, virBitmapFree); break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + VIR_FREE(def->source.subsys.u.vdpa.devpath); + break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: @@ -XXX,XX +XXX,XX @@ virDomainHostdevSubsysMediatedDevDefParseXML(virDomainHostdevDef *def, return 0; } +static int +virDomainHostdevSubsysVDPADefParseXML(xmlNodePtr sourcenode, + virDomainHostdevDef *def) +{ + g_autofree char *devpath = NULL; + virDomainHostdevSubsysVDPA *vdpa = &def->source.subsys.u.vdpa; + + if(!(devpath = virXMLPropString(sourcenode, "dev"))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Missing 'dev' attribute for element <source>")); + return -1; + } + vdpa->devpath = g_steal_pointer(&devpath); + return 0; +} + static int virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, xmlXPathContextPtr ctxt, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, if (virDomainHostdevSubsysMediatedDevDefParseXML(def, ctxt) < 0) return -1; break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + if (virDomainHostdevSubsysVDPADefParseXML(sourcenode, def) < 0) { + return -1; + } + break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } @@ -XXX,XX +XXX,XX @@ virDomainHostdevMatchSubsys(virDomainHostdevDef *a, return 0; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: return virDomainHostdevMatchSubsysMediatedDev(a, b); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + if (STREQ(a->source.subsys.u.vdpa.devpath, + b->source.subsys.u.vdpa.devpath)) { + return 1; + } else { + return 0; + } case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: return 0; } @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefFormatSubsysMdev(virBuffer *buf, virXMLFormatElement(buf, "source", NULL, &sourceChildBuf); } +static void +virDomainHostdevDefFormatSubsysVDPA(virBuffer *buf, + virDomainHostdevDef *def) +{ + g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; + virDomainHostdevSubsysVDPA *vdpasrc = &def->source.subsys.u.vdpa; + virBufferAsprintf(&sourceAttrBuf, " dev='%s'", vdpasrc->devpath); + virXMLFormatElement(buf, "source", &sourceAttrBuf, NULL); +} + static int virDomainHostdevDefFormatSubsys(virBuffer *buf, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefFormatSubsys(virBuffer *buf, virDomainHostdevDefFormatSubsysMdev(buf, def); return 0; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + virDomainHostdevDefFormatSubsysVDPA(buf, def); + return 0; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: default: virReportEnumRangeError(virDomainHostdevSubsysType, def->source.subsys.type); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -XXX,XX +XXX,XX @@ typedef enum { VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV, + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST } virDomainHostdevSubsysType; @@ -XXX,XX +XXX,XX @@ struct _virDomainHostdevSubsysMediatedDev { virTristateSwitch ramfb; }; +struct _virDomainHostdevSubsysVDPA { + char *devpath; /* vDPA device path */ +}; + typedef enum { VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_NONE, VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST, @@ -XXX,XX +XXX,XX @@ struct _virDomainHostdevSubsys { virDomainHostdevSubsysSCSI scsi; virDomainHostdevSubsysSCSIVHost scsi_host; virDomainHostdevSubsysMediatedDev mdev; + virDomainHostdevSubsysVDPA vdpa; } u; }; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev) } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index XXXXXXX..XXXXXXX 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -XXX,XX +XXX,XX @@ typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys; typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediatedDev; +typedef struct _virDomainHostdevSubsysVDPA virDomainHostdevSubsysVDPA; + typedef struct _virDomainHostdevSubsysPCI virDomainHostdevSubsysPCI; typedef struct _virDomainHostdevSubsysSCSI virDomainHostdevSubsysSCSI; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -XXX,XX +XXX,XX @@ qemuBuildHostdevMediatedDevProps(const virDomainDef *def, return g_steal_pointer(&props); } +virJSONValue * +qemuBuildHostdevVDPADevProps(virDomainHostdevDef *dev) +{ + g_autoptr(virJSONValue) props = NULL; + virDomainHostdevSubsysVDPA *vdpasrc = &dev->source.subsys.u.vdpa; + if (virJSONValueObjectAdd(&props, + "s:driver", "vhost-vdpa-device-pci", + "s:vhostdev", vdpasrc->devpath, + NULL) < 0) + return NULL; + return g_steal_pointer(&props); +} qemuBlockStorageSourceAttachData * qemuBuildHostdevSCSIDetachPrepare(virDomainHostdevDef *hostdev, @@ -XXX,XX +XXX,XX @@ qemuBuildHostdevCommandLine(virCommand *cmd, return -1; break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + if (!(devprops = qemuBuildHostdevVDPADevProps(hostdev))) + return -1; + if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, def, qemuCaps) < 0) + return -1; + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -XXX,XX +XXX,XX @@ virJSONValue * qemuBuildHostdevMediatedDevProps(const virDomainDef *def, virDomainHostdevDef *dev); +virJSONValue * +qemuBuildHostdevVDPADevProps(virDomainHostdevDef *dev); + virJSONValue * qemuBuildRedirdevDevProps(const virDomainDef *def, virDomainRedirdevDef *dev); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -XXX,XX +XXX,XX @@ qemuDomainGetHostdevPath(virDomainHostdevDef *dev, virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi; virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host; virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev; + virDomainHostdevSubsysVDPA *vdpasrc = &dev->source.subsys.u.vdpa; + g_autoptr(virUSBDevice) usb = NULL; g_autoptr(virSCSIDevice) scsi = NULL; g_autoptr(virSCSIVHostDevice) host = NULL; @@ -XXX,XX +XXX,XX @@ qemuDomainGetHostdevPath(virDomainHostdevDef *dev, if (!(tmpPath = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) return -1; + perm = VIR_CGROUP_DEVICE_RW; + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + tmpPath = g_strdup(vdpasrc->devpath); perm = VIR_CGROUP_DEVICE_RW; break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -XXX,XX +XXX,XX @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: qemuDomainRemoveMediatedDevice(driver, vm, hostdev); break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -XXX,XX +XXX,XX @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def) case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + /* The vDPA devices don't support migration for now */ + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("cannot migrate a domain with <hostdev mode='subsystem' type='%1$s'>"), virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type)); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -XXX,XX +XXX,XX @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: return qemuValidateDomainMdevDef(hostdev, def, qemuCaps); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: default: virReportEnumRangeError(virDomainHostdevSubsysType, diff --git a/src/security/security_dac.c b/src/security/security_dac.c index XXXXXXX..XXXXXXX 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -XXX,XX +XXX,XX @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; @@ -XXX,XX +XXX,XX @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index XXXXXXX..XXXXXXX 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -XXX,XX +XXX,XX @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; @@ -XXX,XX +XXX,XX @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; -- 2.33.0
The following is the xml of vdpa device: <devices> <hostdev mode='subsystem' type='vdpa'> <source dev='/dev/vhost-vdpa-0'/> </hostdev> </devices> And the command line passed to QEMU is as follows: -device {"driver":"vhost-vdpa-device-pci","vhostdev":"/dev/vhost-vdpa-0"} This solution is selected according to the previous discussion on the solution of supporting the vDPA device. For details, see the following: https://listman.redhat.com/archives/libvir-list/2023-March/239018.html Signed-off-by: libai <libai12@huawei.com> --- src/conf/domain_audit.c | 4 +++ src/conf/domain_conf.c | 47 +++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 6 +++++ src/conf/domain_validate.c | 1 + src/conf/virconftypes.h | 2 ++ src/qemu/qemu_command.c | 19 +++++++++++++ src/qemu/qemu_command.h | 3 +++ src/qemu/qemu_domain.c | 6 +++++ src/qemu/qemu_hotplug.c | 1 + src/qemu/qemu_migration.c | 2 ++ src/qemu/qemu_validate.c | 2 ++ src/security/security_dac.c | 2 ++ src/security/security_selinux.c | 2 ++ 13 files changed, 97 insertions(+) diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -XXX,XX +XXX,XX @@ virDomainAuditHostdev(virDomainObj *vm, virDomainHostdevDef *hostdev, virDomainHostdevSubsysSCSI *scsisrc = &hostdev->source.subsys.u.scsi; virDomainHostdevSubsysSCSIVHost *hostsrc = &hostdev->source.subsys.u.scsi_host; virDomainHostdevSubsysMediatedDev *mdevsrc = &hostdev->source.subsys.u.mdev; + virDomainHostdevSubsysVDPA *vdpasrc = &hostdev->source.subsys.u.vdpa; virUUIDFormat(vm->def->uuid, uuidstr); if (!(vmname = virAuditEncode("vm", vm->def->name))) { @@ -XXX,XX +XXX,XX @@ virDomainAuditHostdev(virDomainObj *vm, virDomainHostdevDef *hostdev, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: address = g_strdup(mdevsrc->uuidstr); break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + address = g_strdup(vdpasrc->devpath); + break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: default: VIR_WARN("Unexpected hostdev type while encoding audit message: %d", diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -XXX,XX +XXX,XX @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, "scsi", "scsi_host", "mdev", + "vdpa", ); VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefClear(virDomainHostdevDef *def) case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: g_clear_pointer(&def->source.subsys.u.pci.origstates, virBitmapFree); break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + VIR_FREE(def->source.subsys.u.vdpa.devpath); + break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: @@ -XXX,XX +XXX,XX @@ virDomainHostdevSubsysMediatedDevDefParseXML(virDomainHostdevDef *def, return 0; } +static int +virDomainHostdevSubsysVDPADefParseXML(xmlNodePtr sourcenode, + virDomainHostdevDef *def) +{ + g_autofree char *devpath = NULL; + virDomainHostdevSubsysVDPA *vdpa = &def->source.subsys.u.vdpa; + + if(!(devpath = virXMLPropString(sourcenode, "dev"))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Missing 'dev' attribute for element <source>")); + return -1; + } + vdpa->devpath = g_steal_pointer(&devpath); + return 0; +} + static int virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, xmlXPathContextPtr ctxt, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, if (virDomainHostdevSubsysMediatedDevDefParseXML(def, ctxt) < 0) return -1; break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + if (virDomainHostdevSubsysVDPADefParseXML(sourcenode, def) < 0) { + return -1; + } + break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefParseXML(virDomainXMLOption *xmlopt, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } @@ -XXX,XX +XXX,XX @@ virDomainHostdevMatchSubsys(virDomainHostdevDef *a, return 0; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: return virDomainHostdevMatchSubsysMediatedDev(a, b); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + if (STREQ(a->source.subsys.u.vdpa.devpath, + b->source.subsys.u.vdpa.devpath)) { + return 1; + } else { + return 0; + } case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: return 0; } @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefFormatSubsysMdev(virBuffer *buf, virXMLFormatElement(buf, "source", NULL, &sourceChildBuf); } +static void +virDomainHostdevDefFormatSubsysVDPA(virBuffer *buf, + virDomainHostdevDef *def) +{ + g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; + virDomainHostdevSubsysVDPA *vdpasrc = &def->source.subsys.u.vdpa; + virBufferAsprintf(&sourceAttrBuf, " dev='%s'", vdpasrc->devpath); + virXMLFormatElement(buf, "source", &sourceAttrBuf, NULL); +} + static int virDomainHostdevDefFormatSubsys(virBuffer *buf, @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefFormatSubsys(virBuffer *buf, virDomainHostdevDefFormatSubsysMdev(buf, def); return 0; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + virDomainHostdevDefFormatSubsysVDPA(buf, def); + return 0; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: default: virReportEnumRangeError(virDomainHostdevSubsysType, def->source.subsys.type); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -XXX,XX +XXX,XX @@ typedef enum { VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV, + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST } virDomainHostdevSubsysType; @@ -XXX,XX +XXX,XX @@ struct _virDomainHostdevSubsysMediatedDev { virTristateSwitch ramfb; }; +struct _virDomainHostdevSubsysVDPA { + char *devpath; /* vDPA device path */ +}; + typedef enum { VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_NONE, VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST, @@ -XXX,XX +XXX,XX @@ struct _virDomainHostdevSubsys { virDomainHostdevSubsysSCSI scsi; virDomainHostdevSubsysSCSIVHost scsi_host; virDomainHostdevSubsysMediatedDev mdev; + virDomainHostdevSubsysVDPA vdpa; } u; }; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index XXXXXXX..XXXXXXX 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -XXX,XX +XXX,XX @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev) } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index XXXXXXX..XXXXXXX 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -XXX,XX +XXX,XX @@ typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys; typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediatedDev; +typedef struct _virDomainHostdevSubsysVDPA virDomainHostdevSubsysVDPA; + typedef struct _virDomainHostdevSubsysPCI virDomainHostdevSubsysPCI; typedef struct _virDomainHostdevSubsysSCSI virDomainHostdevSubsysSCSI; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -XXX,XX +XXX,XX @@ qemuBuildHostdevMediatedDevProps(const virDomainDef *def, return g_steal_pointer(&props); } +virJSONValue * +qemuBuildHostdevVDPADevProps(virDomainHostdevDef *dev) +{ + g_autoptr(virJSONValue) props = NULL; + virDomainHostdevSubsysVDPA *vdpasrc = &dev->source.subsys.u.vdpa; + if (virJSONValueObjectAdd(&props, + "s:driver", "vhost-vdpa-device-pci", + "s:vhostdev", vdpasrc->devpath, + NULL) < 0) + return NULL; + return g_steal_pointer(&props); +} qemuBlockStorageSourceAttachData * qemuBuildHostdevSCSIDetachPrepare(virDomainHostdevDef *hostdev, @@ -XXX,XX +XXX,XX @@ qemuBuildHostdevCommandLine(virCommand *cmd, return -1; break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + if (!(devprops = qemuBuildHostdevVDPADevProps(hostdev))) + return -1; + if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, def, qemuCaps) < 0) + return -1; + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -XXX,XX +XXX,XX @@ virJSONValue * qemuBuildHostdevMediatedDevProps(const virDomainDef *def, virDomainHostdevDef *dev); +virJSONValue * +qemuBuildHostdevVDPADevProps(virDomainHostdevDef *dev); + virJSONValue * qemuBuildRedirdevDevProps(const virDomainDef *def, virDomainRedirdevDef *dev); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -XXX,XX +XXX,XX @@ qemuDomainGetHostdevPath(virDomainHostdevDef *dev, virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi; virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host; virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev; + virDomainHostdevSubsysVDPA *vdpasrc = &dev->source.subsys.u.vdpa; + g_autoptr(virUSBDevice) usb = NULL; g_autoptr(virSCSIDevice) scsi = NULL; g_autoptr(virSCSIVHostDevice) host = NULL; @@ -XXX,XX +XXX,XX @@ qemuDomainGetHostdevPath(virDomainHostdevDef *dev, if (!(tmpPath = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr))) return -1; + perm = VIR_CGROUP_DEVICE_RW; + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + tmpPath = g_strdup(vdpasrc->devpath); perm = VIR_CGROUP_DEVICE_RW; break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -XXX,XX +XXX,XX @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: qemuDomainRemoveMediatedDevice(driver, vm, hostdev); break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: break; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -XXX,XX +XXX,XX @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def) case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + /* The vDPA devices don't support migration for now */ + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("cannot migrate a domain with <hostdev mode='subsystem' type='%1$s'>"), virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type)); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index XXXXXXX..XXXXXXX 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -XXX,XX +XXX,XX @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: return qemuValidateDomainMdevDef(hostdev, def, qemuCaps); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: + break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: default: virReportEnumRangeError(virDomainHostdevSubsysType, diff --git a/src/security/security_dac.c b/src/security/security_dac.c index XXXXXXX..XXXXXXX 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -XXX,XX +XXX,XX @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; @@ -XXX,XX +XXX,XX @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index XXXXXXX..XXXXXXX 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -XXX,XX +XXX,XX @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; @@ -XXX,XX +XXX,XX @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ret = 0; break; -- 2.33.0