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(+)
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 ae875188bd..6906ce7ade 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -344,6 +344,7 @@ 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))) {
@@ -383,6 +384,9 @@ 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 b03a3ff011..e8f6d1457b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1047,6 +1047,7 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys,
"scsi",
"scsi_host",
"mdev",
+ "vdpa",
);
VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend,
@@ -2641,6 +2642,9 @@ 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:
@@ -6160,6 +6164,22 @@ 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,
@@ -6317,6 +6337,11 @@ 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,
@@ -12979,6 +13004,7 @@ 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;
}
@@ -14101,6 +14127,13 @@ 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;
}
@@ -23290,6 +23323,16 @@ 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,
@@ -23317,6 +23360,10 @@ 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 511067a050..ade8b0edec 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -197,6 +197,7 @@ 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;
@@ -289,6 +290,10 @@ 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,
@@ -323,6 +328,7 @@ 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 e04b85fee4..4af84c4f0c 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2214,6 +2214,7 @@ 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 e07f967814..1756c54e7a 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -120,6 +120,8 @@ 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 4ca93bf3dc..121214f4d5 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4958,6 +4958,18 @@ 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,
@@ -5154,6 +5166,13 @@ 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 5fdb138030..dff18350b5 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -198,6 +198,9 @@ 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 63b13b6875..0cd485a459 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -10533,6 +10533,8 @@ 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;
@@ -10603,6 +10605,10 @@ 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 5072798cb7..7d89899223 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4546,6 +4546,7 @@ 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 ed41a03851..9220ef1ab1 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1295,6 +1295,8 @@ 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 b8d5e9bd74..ea3d4e1a39 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -2566,6 +2566,8 @@ 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 c7dc145621..24f3de5d15 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1313,6 +1313,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
ret = 0;
break;
@@ -1469,6 +1470,7 @@ 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 e3e6a6115f..5cb6612fbc 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2265,6 +2265,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
ret = 0;
break;
@@ -2493,6 +2494,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
ret = 0;
break;
--
2.33.0
On Mon, Apr 24, 2023 at 11:55 AM libai <libai12@huawei.com> wrote: > > 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 It would be also helpful if you can point to some links to explain the generic vDPA device. Adding Laine and Jonathon for comments. Thanks > > 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 ae875188bd..6906ce7ade 100644 > --- a/src/conf/domain_audit.c > +++ b/src/conf/domain_audit.c > @@ -344,6 +344,7 @@ 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))) { > @@ -383,6 +384,9 @@ 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 b03a3ff011..e8f6d1457b 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -1047,6 +1047,7 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, > "scsi", > "scsi_host", > "mdev", > + "vdpa", > ); > > VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend, > @@ -2641,6 +2642,9 @@ 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: > @@ -6160,6 +6164,22 @@ 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, > @@ -6317,6 +6337,11 @@ 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, > @@ -12979,6 +13004,7 @@ 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; > } > @@ -14101,6 +14127,13 @@ 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; > } > @@ -23290,6 +23323,16 @@ 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, > @@ -23317,6 +23360,10 @@ 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 511067a050..ade8b0edec 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -197,6 +197,7 @@ 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; > @@ -289,6 +290,10 @@ 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, > @@ -323,6 +328,7 @@ 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 e04b85fee4..4af84c4f0c 100644 > --- a/src/conf/domain_validate.c > +++ b/src/conf/domain_validate.c > @@ -2214,6 +2214,7 @@ 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 e07f967814..1756c54e7a 100644 > --- a/src/conf/virconftypes.h > +++ b/src/conf/virconftypes.h > @@ -120,6 +120,8 @@ 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 4ca93bf3dc..121214f4d5 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -4958,6 +4958,18 @@ 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, > @@ -5154,6 +5166,13 @@ 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 5fdb138030..dff18350b5 100644 > --- a/src/qemu/qemu_command.h > +++ b/src/qemu/qemu_command.h > @@ -198,6 +198,9 @@ 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 63b13b6875..0cd485a459 100644 > --- a/src/qemu/qemu_domain.c > +++ b/src/qemu/qemu_domain.c > @@ -10533,6 +10533,8 @@ 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; > @@ -10603,6 +10605,10 @@ 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 5072798cb7..7d89899223 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -4546,6 +4546,7 @@ 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 ed41a03851..9220ef1ab1 100644 > --- a/src/qemu/qemu_migration.c > +++ b/src/qemu/qemu_migration.c > @@ -1295,6 +1295,8 @@ 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 b8d5e9bd74..ea3d4e1a39 100644 > --- a/src/qemu/qemu_validate.c > +++ b/src/qemu/qemu_validate.c > @@ -2566,6 +2566,8 @@ 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 c7dc145621..24f3de5d15 100644 > --- a/src/security/security_dac.c > +++ b/src/security/security_dac.c > @@ -1313,6 +1313,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, > break; > } > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: > ret = 0; > break; > @@ -1469,6 +1470,7 @@ 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 e3e6a6115f..5cb6612fbc 100644 > --- a/src/security/security_selinux.c > +++ b/src/security/security_selinux.c > @@ -2265,6 +2265,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, > break; > } > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: > ret = 0; > break; > @@ -2493,6 +2494,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, > break; > } > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: > ret = 0; > break; > -- > 2.33.0 >
ping 在 2023/4/24 11:36, libai 写道: > 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 ae875188bd..6906ce7ade 100644 > --- a/src/conf/domain_audit.c > +++ b/src/conf/domain_audit.c > @@ -344,6 +344,7 @@ 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))) { > @@ -383,6 +384,9 @@ 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 b03a3ff011..e8f6d1457b 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -1047,6 +1047,7 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, > "scsi", > "scsi_host", > "mdev", > + "vdpa", > ); > > VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend, > @@ -2641,6 +2642,9 @@ 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: > @@ -6160,6 +6164,22 @@ 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, > @@ -6317,6 +6337,11 @@ 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, > @@ -12979,6 +13004,7 @@ 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; > } > @@ -14101,6 +14127,13 @@ 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; > } > @@ -23290,6 +23323,16 @@ 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, > @@ -23317,6 +23360,10 @@ 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 511067a050..ade8b0edec 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -197,6 +197,7 @@ 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; > @@ -289,6 +290,10 @@ 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, > @@ -323,6 +328,7 @@ 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 e04b85fee4..4af84c4f0c 100644 > --- a/src/conf/domain_validate.c > +++ b/src/conf/domain_validate.c > @@ -2214,6 +2214,7 @@ 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 e07f967814..1756c54e7a 100644 > --- a/src/conf/virconftypes.h > +++ b/src/conf/virconftypes.h > @@ -120,6 +120,8 @@ 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 4ca93bf3dc..121214f4d5 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -4958,6 +4958,18 @@ 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, > @@ -5154,6 +5166,13 @@ 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 5fdb138030..dff18350b5 100644 > --- a/src/qemu/qemu_command.h > +++ b/src/qemu/qemu_command.h > @@ -198,6 +198,9 @@ 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 63b13b6875..0cd485a459 100644 > --- a/src/qemu/qemu_domain.c > +++ b/src/qemu/qemu_domain.c > @@ -10533,6 +10533,8 @@ 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; > @@ -10603,6 +10605,10 @@ 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 5072798cb7..7d89899223 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -4546,6 +4546,7 @@ 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 ed41a03851..9220ef1ab1 100644 > --- a/src/qemu/qemu_migration.c > +++ b/src/qemu/qemu_migration.c > @@ -1295,6 +1295,8 @@ 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 b8d5e9bd74..ea3d4e1a39 100644 > --- a/src/qemu/qemu_validate.c > +++ b/src/qemu/qemu_validate.c > @@ -2566,6 +2566,8 @@ 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 c7dc145621..24f3de5d15 100644 > --- a/src/security/security_dac.c > +++ b/src/security/security_dac.c > @@ -1313,6 +1313,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr, > break; > } > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: > ret = 0; > break; > @@ -1469,6 +1470,7 @@ 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 e3e6a6115f..5cb6612fbc 100644 > --- a/src/security/security_selinux.c > +++ b/src/security/security_selinux.c > @@ -2265,6 +2265,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr, > break; > } > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: > ret = 0; > break; > @@ -2493,6 +2494,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr, > break; > } > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_VDPA: > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: > ret = 0; > break;
© 2016 - 2024 Red Hat, Inc.