|
|
9119d9 |
From d7ec27fd43a6c58e81fd0f7a2149d0f81929c3e1 Mon Sep 17 00:00:00 2001
|
|
|
9119d9 |
Message-Id: <d7ec27fd43a6c58e81fd0f7a2149d0f81929c3e1@dist-git>
|
|
|
9119d9 |
From: Martin Kletzander <mkletzan@redhat.com>
|
|
|
9119d9 |
Date: Fri, 3 Oct 2014 22:54:57 +0200
|
|
|
9119d9 |
Subject: [PATCH] qemu: Build command line for ivshmem device
|
|
|
9119d9 |
|
|
|
9119d9 |
https://bugzilla.redhat.com/show_bug.cgi?id=1126991
|
|
|
9119d9 |
|
|
|
9119d9 |
This patch implements support for the ivshmem device in QEMU.
|
|
|
9119d9 |
|
|
|
9119d9 |
Signed-off-by: Maxime Leroy <maxime.leroy@6wind.com>
|
|
|
9119d9 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
9119d9 |
(cherry picked from commit b90a9a637490acd7f35c6dc52d6e55b5a1054f34)
|
|
|
9119d9 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
9119d9 |
---
|
|
|
9119d9 |
src/conf/domain_conf.c | 4 +-
|
|
|
9119d9 |
src/qemu/qemu_command.c | 117 +++++++++++++++++++++
|
|
|
9119d9 |
.../qemuxml2argv-shmem-invalid-size.xml | 24 +++++
|
|
|
9119d9 |
.../qemuxml2argv-shmem-small-size.xml | 24 +++++
|
|
|
9119d9 |
tests/qemuxml2argvdata/qemuxml2argv-shmem.args | 16 +++
|
|
|
9119d9 |
tests/qemuxml2argvtest.c | 5 +
|
|
|
9119d9 |
6 files changed, 188 insertions(+), 2 deletions(-)
|
|
|
9119d9 |
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-shmem-invalid-size.xml
|
|
|
9119d9 |
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-shmem-small-size.xml
|
|
|
9119d9 |
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-shmem.args
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
|
9119d9 |
index 2768660..d61358b 100644
|
|
|
9119d9 |
--- a/src/conf/domain_conf.c
|
|
|
9119d9 |
+++ b/src/conf/domain_conf.c
|
|
|
9119d9 |
@@ -9743,7 +9743,7 @@ virDomainShmemDefParseXML(xmlNodePtr node,
|
|
|
9119d9 |
1, ULLONG_MAX, false) < 0)
|
|
|
9119d9 |
goto cleanup;
|
|
|
9119d9 |
|
|
|
9119d9 |
- if ((server = virXPathNode("./server", ctxt))) {
|
|
|
9119d9 |
+ if ((server = virXPathNode("./server[1]", ctxt))) {
|
|
|
9119d9 |
def->server.enabled = true;
|
|
|
9119d9 |
|
|
|
9119d9 |
if ((tmp = virXMLPropString(server, "path")))
|
|
|
9119d9 |
@@ -9751,7 +9751,7 @@ virDomainShmemDefParseXML(xmlNodePtr node,
|
|
|
9119d9 |
VIR_FREE(tmp);
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
- if ((msi = virXPathNode("./msi", ctxt))) {
|
|
|
9119d9 |
+ if ((msi = virXPathNode("./msi[1]", ctxt))) {
|
|
|
9119d9 |
def->msi.enabled = true;
|
|
|
9119d9 |
|
|
|
9119d9 |
if ((tmp = virXMLPropString(msi, "vectors")) &&
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
|
9119d9 |
index 6c4e2ff..3adf19e 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_command.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_command.c
|
|
|
9119d9 |
@@ -1027,6 +1027,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
|
|
|
9119d9 |
if (virAsprintf(&def->hubs[i]->info.alias, "hub%zu", i) < 0)
|
|
|
9119d9 |
return -1;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
+ for (i = 0; i < def->nshmems; i++) {
|
|
|
9119d9 |
+ if (virAsprintf(&def->shmems[i]->info.alias, "shmem%zu", i) < 0)
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
for (i = 0; i < def->nsmartcards; i++) {
|
|
|
9119d9 |
if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%zu", i) < 0)
|
|
|
9119d9 |
return -1;
|
|
|
9119d9 |
@@ -7495,6 +7499,114 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
static int
|
|
|
9119d9 |
+qemuBuildShmemDevCmd(virCommandPtr cmd,
|
|
|
9119d9 |
+ virDomainDefPtr def,
|
|
|
9119d9 |
+ virDomainShmemDefPtr shmem,
|
|
|
9119d9 |
+ virQEMUCapsPtr qemuCaps)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM)) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
9119d9 |
+ _("ivshmem device is not supported "
|
|
|
9119d9 |
+ "with this QEMU binary"));
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ virBufferAddLit(&buf, "ivshmem");
|
|
|
9119d9 |
+ if (shmem->size) {
|
|
|
9119d9 |
+ /*
|
|
|
9119d9 |
+ * Thanks to our parsing code, we have a guarantee that the
|
|
|
9119d9 |
+ * size is power of two and is at least a mebibyte in size.
|
|
|
9119d9 |
+ * But because it may change inthe future, the checks are
|
|
|
9119d9 |
+ * doubled in here.
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+ if (shmem->size & (shmem->size - 1)) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
9119d9 |
+ _("shmem size must be a power of two"));
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (shmem->size < 1024 * 1024) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
9119d9 |
+ _("shmem size must be at least 1 MiB"));
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ virBufferAsprintf(&buf, ",size=%llum",
|
|
|
9119d9 |
+ VIR_DIV_UP(shmem->size, 1024 * 1024));
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!shmem->server.enabled) {
|
|
|
9119d9 |
+ virBufferAsprintf(&buf, ",shm=%s", shmem->name);
|
|
|
9119d9 |
+ } else {
|
|
|
9119d9 |
+ virBufferAsprintf(&buf, ",chardev=char%s", shmem->info.alias);
|
|
|
9119d9 |
+ if (shmem->msi.enabled) {
|
|
|
9119d9 |
+ virBufferAddLit(&buf, ",msi=on");
|
|
|
9119d9 |
+ if (shmem->msi.vectors)
|
|
|
9119d9 |
+ virBufferAsprintf(&buf, ",vectors=%u", shmem->msi.vectors);
|
|
|
9119d9 |
+ if (shmem->msi.ioeventfd)
|
|
|
9119d9 |
+ virBufferAsprintf(&buf, ",ioeventfd=%s",
|
|
|
9119d9 |
+ virTristateSwitchTypeToString(shmem->msi.ioeventfd));
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (qemuBuildDeviceAddressStr(&buf, def, &shmem->info, qemuCaps) < 0)
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (virBufferCheckError(&buf) < 0)
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ virCommandAddArg(cmd, "-device");
|
|
|
9119d9 |
+ virCommandAddArgBuffer(cmd, &buf;;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ return 0;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ error:
|
|
|
9119d9 |
+ virBufferFreeAndReset(&buf;;
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+static int
|
|
|
9119d9 |
+qemuBuildShmemCommandLine(virCommandPtr cmd,
|
|
|
9119d9 |
+ virDomainDefPtr def,
|
|
|
9119d9 |
+ virDomainShmemDefPtr shmem,
|
|
|
9119d9 |
+ virQEMUCapsPtr qemuCaps)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ if (qemuBuildShmemDevCmd(cmd, def, shmem, qemuCaps) < 0)
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (shmem->server.enabled) {
|
|
|
9119d9 |
+ char *devstr = NULL;
|
|
|
9119d9 |
+ virDomainChrSourceDef source = {
|
|
|
9119d9 |
+ .type = VIR_DOMAIN_CHR_TYPE_UNIX,
|
|
|
9119d9 |
+ .data.nix = {
|
|
|
9119d9 |
+ .path = shmem->server.path,
|
|
|
9119d9 |
+ .listen = false,
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ };
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!shmem->server.path &&
|
|
|
9119d9 |
+ virAsprintf(&source.data.nix.path,
|
|
|
9119d9 |
+ "/var/lib/libvirt/shmem-%s-sock",
|
|
|
9119d9 |
+ shmem->name) < 0)
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ devstr = qemuBuildChrChardevStr(&source, shmem->info.alias, qemuCaps);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!shmem->server.path)
|
|
|
9119d9 |
+ VIR_FREE(source.data.nix.path);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!devstr)
|
|
|
9119d9 |
+ return -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ virCommandAddArg(cmd, "-chardev");
|
|
|
9119d9 |
+ virCommandAddArg(cmd, devstr);
|
|
|
9119d9 |
+ VIR_FREE(devstr);
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ return 0;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+static int
|
|
|
9119d9 |
qemuBuildChrDeviceCommandLine(virCommandPtr cmd,
|
|
|
9119d9 |
virDomainDefPtr def,
|
|
|
9119d9 |
virDomainChrDefPtr chr,
|
|
|
9119d9 |
@@ -9683,6 +9795,11 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
+ for (i = 0; i < def->nshmems; i++) {
|
|
|
9119d9 |
+ if (qemuBuildShmemCommandLine(cmd, def, def->shmems[i], qemuCaps))
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
if (mlock) {
|
|
|
9119d9 |
unsigned long long memKB;
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-shmem-invalid-size.xml b/tests/qemuxml2argvdata/qemuxml2argv-shmem-invalid-size.xml
|
|
|
9119d9 |
new file mode 100644
|
|
|
9119d9 |
index 0000000..992f8fd
|
|
|
9119d9 |
--- /dev/null
|
|
|
9119d9 |
+++ b/tests/qemuxml2argvdata/qemuxml2argv-shmem-invalid-size.xml
|
|
|
9119d9 |
@@ -0,0 +1,24 @@
|
|
|
9119d9 |
+<domain type='qemu'>
|
|
|
9119d9 |
+ <name>QEMUGuest1</name>
|
|
|
9119d9 |
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
|
|
9119d9 |
+ <memory unit='KiB'>219136</memory>
|
|
|
9119d9 |
+ <currentMemory unit='KiB'>219136</currentMemory>
|
|
|
9119d9 |
+ <vcpu placement='static'>1</vcpu>
|
|
|
9119d9 |
+ <os>
|
|
|
9119d9 |
+ <type arch='i686' machine='pc'>hvm</type>
|
|
|
9119d9 |
+ <boot dev='hd'/>
|
|
|
9119d9 |
+ </os>
|
|
|
9119d9 |
+ <clock offset='utc'/>
|
|
|
9119d9 |
+ <on_poweroff>destroy</on_poweroff>
|
|
|
9119d9 |
+ <on_reboot>restart</on_reboot>
|
|
|
9119d9 |
+ <on_crash>destroy</on_crash>
|
|
|
9119d9 |
+ <devices>
|
|
|
9119d9 |
+ <emulator>/usr/bin/qemu</emulator>
|
|
|
9119d9 |
+ <controller type='usb' index='0'/>
|
|
|
9119d9 |
+ <controller type='pci' index='0' model='pci-root'/>
|
|
|
9119d9 |
+ <memballoon model='none'/>
|
|
|
9119d9 |
+ <shmem name='shmem0'>
|
|
|
9119d9 |
+ <size unit='K'>12345</size>
|
|
|
9119d9 |
+ </shmem>
|
|
|
9119d9 |
+ </devices>
|
|
|
9119d9 |
+</domain>
|
|
|
9119d9 |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-shmem-small-size.xml b/tests/qemuxml2argvdata/qemuxml2argv-shmem-small-size.xml
|
|
|
9119d9 |
new file mode 100644
|
|
|
9119d9 |
index 0000000..8f99b14
|
|
|
9119d9 |
--- /dev/null
|
|
|
9119d9 |
+++ b/tests/qemuxml2argvdata/qemuxml2argv-shmem-small-size.xml
|
|
|
9119d9 |
@@ -0,0 +1,24 @@
|
|
|
9119d9 |
+<domain type='qemu'>
|
|
|
9119d9 |
+ <name>QEMUGuest1</name>
|
|
|
9119d9 |
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
|
|
9119d9 |
+ <memory unit='KiB'>219136</memory>
|
|
|
9119d9 |
+ <currentMemory unit='KiB'>219136</currentMemory>
|
|
|
9119d9 |
+ <vcpu placement='static'>1</vcpu>
|
|
|
9119d9 |
+ <os>
|
|
|
9119d9 |
+ <type arch='i686' machine='pc'>hvm</type>
|
|
|
9119d9 |
+ <boot dev='hd'/>
|
|
|
9119d9 |
+ </os>
|
|
|
9119d9 |
+ <clock offset='utc'/>
|
|
|
9119d9 |
+ <on_poweroff>destroy</on_poweroff>
|
|
|
9119d9 |
+ <on_reboot>restart</on_reboot>
|
|
|
9119d9 |
+ <on_crash>destroy</on_crash>
|
|
|
9119d9 |
+ <devices>
|
|
|
9119d9 |
+ <emulator>/usr/bin/qemu</emulator>
|
|
|
9119d9 |
+ <controller type='usb' index='0'/>
|
|
|
9119d9 |
+ <controller type='pci' index='0' model='pci-root'/>
|
|
|
9119d9 |
+ <memballoon model='none'/>
|
|
|
9119d9 |
+ <shmem name='shmem0'>
|
|
|
9119d9 |
+ <size unit='K'>16</size>
|
|
|
9119d9 |
+ </shmem>
|
|
|
9119d9 |
+ </devices>
|
|
|
9119d9 |
+</domain>
|
|
|
9119d9 |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-shmem.args b/tests/qemuxml2argvdata/qemuxml2argv-shmem.args
|
|
|
9119d9 |
new file mode 100644
|
|
|
9119d9 |
index 0000000..a3d3cc8
|
|
|
9119d9 |
--- /dev/null
|
|
|
9119d9 |
+++ b/tests/qemuxml2argvdata/qemuxml2argv-shmem.args
|
|
|
9119d9 |
@@ -0,0 +1,16 @@
|
|
|
9119d9 |
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
|
|
|
9119d9 |
+/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults \
|
|
|
9119d9 |
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
|
|
|
9119d9 |
+-device ivshmem,shm=shmem0 \
|
|
|
9119d9 |
+-device ivshmem,size=128m,shm=shmem1 \
|
|
|
9119d9 |
+-device ivshmem,size=256m,shm=shmem2 \
|
|
|
9119d9 |
+-device ivshmem,size=512m,chardev=charshmem3 \
|
|
|
9119d9 |
+-chardev socket,id=charshmem3,path=/var/lib/libvirt/shmem-shmem3-sock \
|
|
|
9119d9 |
+-device ivshmem,size=1024m,chardev=charshmem4 \
|
|
|
9119d9 |
+-chardev socket,id=charshmem4,path=/tmp/shmem4-sock \
|
|
|
9119d9 |
+-device ivshmem,size=2048m,chardev=charshmem5,msi=on,ioeventfd=off \
|
|
|
9119d9 |
+-chardev socket,id=charshmem5,path=/tmp/shmem5-sock \
|
|
|
9119d9 |
+-device ivshmem,size=4096m,chardev=charshmem6,msi=on,vectors=16 \
|
|
|
9119d9 |
+-chardev socket,id=charshmem6,path=/tmp/shmem6-sock \
|
|
|
9119d9 |
+-device ivshmem,size=8192m,chardev=charshmem7,msi=on,vectors=32,ioeventfd=on \
|
|
|
9119d9 |
+-chardev socket,id=charshmem7,path=/tmp/shmem7-sock
|
|
|
9119d9 |
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
|
|
|
9119d9 |
index ae8bbfc..dafe683 100644
|
|
|
9119d9 |
--- a/tests/qemuxml2argvtest.c
|
|
|
9119d9 |
+++ b/tests/qemuxml2argvtest.c
|
|
|
9119d9 |
@@ -1463,6 +1463,11 @@ mymain(void)
|
|
|
9119d9 |
|
|
|
9119d9 |
DO_TEST("fips-enabled", QEMU_CAPS_ENABLE_FIPS);
|
|
|
9119d9 |
|
|
|
9119d9 |
+ DO_TEST("shmem", QEMU_CAPS_PCIDEVICE,
|
|
|
9119d9 |
+ QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_IVSHMEM);
|
|
|
9119d9 |
+ DO_TEST_FAILURE("shmem", NONE);
|
|
|
9119d9 |
+ DO_TEST_FAILURE("shmem-invalid-size", NONE);
|
|
|
9119d9 |
+ DO_TEST_FAILURE("shmem-small-size", NONE);
|
|
|
9119d9 |
DO_TEST_PARSE_ERROR("shmem-msi-only", NONE);
|
|
|
9119d9 |
|
|
|
9119d9 |
virObjectUnref(driver.config);
|
|
|
9119d9 |
--
|
|
|
9119d9 |
2.1.2
|
|
|
9119d9 |
|