diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index c70377ba48..10a692de25 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6829,6 +6829,7 @@ qemu-kvm -net nic,model=? /dev/null <size unit='M'>4</size> </shmem> <shmem name='shmem_server'> + <model type='ivshmem'/> <size unit='M'>2</size> <server path='/tmp/socket-shmem'/> <msi vectors='32' ioeventfd='on'/> @@ -6843,6 +6844,13 @@ qemu-kvm -net nic,model=? /dev/null The shmem element has one mandatory attribute, name to identify the shared memory. +
model
+
+ Attribute type of the optional element model + specifies the model of the underlying device providing the + shmem device. Currently the only supported model is + ivshmem. +
size
The optional size element specifies the size of the shared diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index dba9187aa7..99e0eb6cb4 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3591,6 +3591,15 @@ + + + + + ivshmem + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 03506cbec1..108a48ee97 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -844,6 +844,9 @@ VIR_ENUM_IMPL(virDomainBlockJob, VIR_DOMAIN_BLOCK_JOB_TYPE_LAST, VIR_ENUM_IMPL(virDomainMemoryModel, VIR_DOMAIN_MEMORY_MODEL_LAST, "", "dimm") +VIR_ENUM_IMPL(virDomainShmemModel, VIR_DOMAIN_SHMEM_MODEL_LAST, + "ivshmem") + static virClassPtr virDomainObjClass; static virClassPtr virDomainXMLOptionClass; static void virDomainObjDispose(void *obj); @@ -12351,6 +12354,20 @@ virDomainShmemDefParseXML(xmlNodePtr node, ctxt->node = node; + tmp = virXPathString("string(./model/@type)", ctxt); + if (tmp) { + /* If there's none, we will automatically have the first one + * (as default). Unfortunately this has to be done for + * compatibility reasons. */ + if ((def->model = virDomainShmemModelTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Unknown shmem model type '%s'"), tmp); + goto cleanup; + } + + VIR_FREE(tmp); + } + if (!(def->name = virXMLPropString(node, "name"))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("shmem element must contain 'name' attribute")); @@ -14939,6 +14956,9 @@ virDomainShmemDefEquals(virDomainShmemDefPtr src, if (src->size != dst->size) return false; + if (src->model != dst->model) + return false; + if (src->server.enabled != dst->server.enabled) return false; @@ -18927,6 +18947,15 @@ virDomainShmemDefCheckABIStability(virDomainShmemDefPtr src, return false; } + if (src->model != dst->model) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target shared memory model '%s' does not match " + "source model '%s'"), + virDomainShmemModelTypeToString(dst->model), + virDomainShmemModelTypeToString(src->model)); + return false; + } + if (src->size != dst->size) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target shared memory size '%llu' does not match " @@ -21980,20 +22009,13 @@ virDomainShmemDefFormat(virBufferPtr buf, virDomainShmemDefPtr def, unsigned int flags) { - virBufferEscapeString(buf, "name); - - if (!def->size && - !def->server.enabled && - !def->msi.enabled && - !virDomainDeviceInfoNeedsFormat(&def->info, flags)) { - virBufferAddLit(buf, "/>\n"); - return 0; - } else { - virBufferAddLit(buf, ">\n"); - } + virBufferEscapeString(buf, "\n", def->name); virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "\n", + virDomainShmemModelTypeToString(def->model)); + if (def->size) virBufferAsprintf(buf, "%llu\n", def->size >> 20); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 24aa79cdc9..d2a9289e07 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1562,9 +1562,16 @@ struct _virDomainNVRAMDef { virDomainDeviceInfo info; }; +typedef enum { + VIR_DOMAIN_SHMEM_MODEL_IVSHMEM, + + VIR_DOMAIN_SHMEM_MODEL_LAST +} virDomainShmemModel; + struct _virDomainShmemDef { char *name; unsigned long long size; + int model; /* enum virDomainShmemModel */ struct { bool enabled; virDomainChrSourceDef chr; @@ -3084,6 +3091,7 @@ VIR_ENUM_DECL(virDomainTPMBackend) VIR_ENUM_DECL(virDomainMemoryModel) VIR_ENUM_DECL(virDomainMemoryBackingModel) VIR_ENUM_DECL(virDomainIOMMUModel) +VIR_ENUM_DECL(virDomainShmemModel) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainNostateReason) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 162fda54f9..74dd5271a8 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -474,6 +474,8 @@ virDomainShmemDefFind; virDomainShmemDefFree; virDomainShmemDefInsert; virDomainShmemDefRemove; +virDomainShmemModelTypeFromString; +virDomainShmemModelTypeToString; virDomainShutdownReasonTypeFromString; virDomainShutdownReasonTypeToString; virDomainShutoffReasonTypeFromString; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b68da3db5f..5ed288c02a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8525,7 +8525,16 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager, return -1; } - if (!(devstr = qemuBuildShmemDevLegacyStr(def, shmem, qemuCaps))) + switch ((virDomainShmemModel)shmem->model) { + case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM: + devstr = qemuBuildShmemDevLegacyStr(def, shmem, qemuCaps); + break; + + case VIR_DOMAIN_SHMEM_MODEL_LAST: + break; + } + + if (!devstr) return -1; virCommandAddArgList(cmd, "-device", devstr, NULL); VIR_FREE(devstr); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-shmem.xml b/tests/qemuxml2argvdata/qemuxml2argv-shmem.xml index 5bc4904489..b56e9e1878 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-shmem.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-shmem.xml @@ -28,6 +28,7 @@
+ 512 @@ -41,6 +42,7 @@ + 4096 diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-shmem.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-shmem.xml index 1197f361e3..5602913648 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-shmem.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-shmem.xml @@ -22,39 +22,47 @@ +
+ 128
+ 256
+ 512
+ 1024
+ 2048
+ 4096
+ 8192