This patch implements support for the ivshmem device
in QEMU.
Example from this xml:
<ivshmem server='yes'' role='master'/>
<source file='/tmp/socket-ivshmem0'/>
<size unit='M'>32</size>
<msi vectors='32' ioeventfd='on'/>
</ivshmem>
The following QEMU line is built:
-device ivshmem,size=32m,vectors=32,chardev=charivshmem0,msi=on,
ioeventfd=on,role=master
-chardev socket,path=/tmp/socket-ivshmem0,id=charivshmem0
Note: PCI hotpluging has not be implemented.
Signed-off-by: Maxime Leroy <maxime.leroy(a)6wind.com>
---
src/qemu/qemu_command.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_command.h | 4 +++
src/qemu/qemu_hotplug.c | 1 +
3 files changed, 82 insertions(+)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a5ff10a..b434023 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1034,6 +1034,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr
qemuCaps)
if (virAsprintf(&def->hubs[i]->info.alias, "hub%zu", i) <
0)
return -1;
}
+ for (i = 0; i < def->nivshmems; i++) {
+ if (virAsprintf(&def->ivshmems[i]->info.alias, "ivshmem%zu",
i) < 0)
+ return -1;
+ }
for (i = 0; i < def->nsmartcards; i++) {
if (virAsprintf(&def->smartcards[i]->info.alias,
"smartcard%zu", i) < 0)
return -1;
@@ -5032,6 +5036,53 @@ qemuBuildRedirdevDevStr(virDomainDefPtr def,
}
char *
+qemuBuildIvshmemDevStr(virDomainDefPtr def,
+ virDomainIvshmemDefPtr dev,
+ virQEMUCapsPtr qemuCaps)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("ivshmem device is not supported by QEMU"));
+ goto error;
+ }
+
+ virBufferAddLit(&buf, "ivshmem");
+ if (dev->size)
+ virBufferAsprintf(&buf, ",size=%llum", dev->size / (1024 *
1024));
+ if (dev->role)
+ virBufferAsprintf(&buf, ",role=%s",
+ virDomainIvshmemRoleTypeToString(dev->role));
+
+ if (dev->use_server == VIR_DOMAIN_IVSHMEM_SERVER_DISABLED)
+ virBufferAsprintf(&buf, ",shm=%s", dev->file);
+ else {
+ virBufferAsprintf(&buf, ",chardev=char%s", dev->info.alias);
+ if (dev->msi.enabled) {
+ virBufferAddLit(&buf, ",msi=on");
+ if (dev->msi.vectors)
+ virBufferAsprintf(&buf, ",vectors=%u",
dev->msi.vectors);
+ if (dev->msi.ioeventfd)
+ virBufferAsprintf(&buf, ",ioeventfd=%s",
+ virTristateSwitchTypeToString(dev->msi.ioeventfd));
+ }
+ }
+
+ if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
+ goto error;
+
+ if (virBufferCheckError(&buf) < 0)
+ goto error;
+
+ return virBufferContentAndReset(&buf);
+
+ error:
+ virBufferFreeAndReset(&buf);
+ return NULL;
+}
+
+char *
qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
virDomainHostdevDefPtr dev,
virQEMUCapsPtr qemuCaps)
@@ -9317,6 +9368,32 @@ qemuBuildCommandLine(virConnectPtr conn,
}
}
+ for (i = 0; i < def->nivshmems; i++) {
+ virDomainIvshmemDefPtr ivshmem = def->ivshmems[i];
+ char *devstr;
+
+ virCommandAddArg(cmd, "-device");
+ if (!(devstr = qemuBuildIvshmemDevStr(def, ivshmem, qemuCaps)))
+ goto error;
+ virCommandAddArg(cmd, devstr);
+ VIR_FREE(devstr);
+
+ if (ivshmem->use_server == VIR_DOMAIN_IVSHMEM_SERVER_ENABLED) {
+ virDomainChrSourceDef source;
+
+ source.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+ source.data.nix.path = ivshmem->file;
+ source.data.nix.listen = false;
+
+ virCommandAddArg(cmd, "-chardev");
+ if (!(devstr = qemuBuildChrChardevStr(&source, ivshmem->info.alias,
+ qemuCaps)))
+ goto error;
+ virCommandAddArg(cmd, devstr);
+ VIR_FREE(devstr);
+ }
+ }
+
if (mlock) {
unsigned long long memKB;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index b71e964..f3d301a 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -185,6 +185,10 @@ char * qemuBuildHubDevStr(virDomainDefPtr def,
char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
virDomainRedirdevDefPtr dev,
virQEMUCapsPtr qemuCaps);
+char * qemuBuildIvshmemDevStr(virDomainDefPtr def,
+ virDomainIvshmemDefPtr dev,
+ virQEMUCapsPtr qemuCaps);
+
int qemuNetworkIfaceConnect(virDomainDefPtr def,
virConnectPtr conn,
virQEMUDriverPtr driver,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 004b6a4..7be3a04 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2824,6 +2824,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_RNG:
+ case VIR_DOMAIN_DEVICE_IVSHMEM:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("don't know how to remove a %s device"),
--
1.9.3