[PATCH 03/10] conf: Introduce virtio-mem <memory/> model

Daniel Henrique Barboza danielhb413 at gmail.com
Fri Jan 22 18:16:59 UTC 2021



On 1/22/21 9:50 AM, Michal Privoznik wrote:
> The virtio-mem is paravirtualized mechanism of adding/removing
> memory to/from a VM. A virtio-mem-pci device is split into blocks
> of equal size which are then exposed (all or only a requested
> portion of them) to the guest kernel to use as regular memory.
> Therefore, the device has two important attributes:
> 
>    1) block-size, which defines the size of a block
>    2) requested-size, which defines how much memory (in bytes)
>       is the device requested to expose to the guest.
> 
> The 'block-size' is configured on command line and immutable
> throughout device's lifetime. The 'requested-size' can be set on
> the command line too, but also is adjustable via monitor. In
> fact, that is how management software places its requests to
> change the memory allocation. If it wants to give more memory to
> the guest it changes 'requested-size' to a bigger value, and if it
> wants to shrink guest memory it changes the 'requested-size' to a
> smaller value. Note, value of zero means that guest should
> release all memory offered by the device. Of course, guest has to
> cooperate. Therefore, there is a third attribute 'size' which is
> read only and reflects how much memory the guest still has. This
> can be different to 'requested-size', obviously. Because of name
> clash, I've named it 'actualsize' and it is dealt with in future
> commits (it is a runtime information anyway).
> 
> In the backend, memory for virtio-mem is backed by usual objects:
> memory-backend-{ram,file,memfd} and their size puts the cap on
> the amount of memory that a virtio-mem device can offer to a
> guest. But we are already able to express this info using <size/>
> under <target/>.
> 
> Therefore, we need only two more elements to cover 'block-size'
> and 'requested-size' attributes. This is the XML I've came up
> with:
> 
>    <memory model='virtio-mem'>
>      <source>
>        <nodemask>1-3</nodemask>
>        <pagesize unit='KiB'>2048</pagesize>
>      </source>
>      <target>
>        <size unit='KiB'>2097152</size>
>        <node>0</node>
>        <block unit='KiB'>2048</block>
>        <requested unit='KiB'>1048576</requested>
>      </target>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
>    </memory>
> 
> I hope by now it is obvious that:
> 
>    1) 'requested-size' must be an integer multiple of
>       'block-size', and
>    2) virtio-mem-pci device goes onto PCI bus and thus needs PCI
>       address.
> 
> Then there is a limitation that the minimal 'block-size' is
> transparent huge page size (I'll leave this without explanation).
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>   docs/formatdomain.rst                         | 35 ++++++++--
>   docs/schemas/domaincommon.rng                 | 11 ++++
>   src/conf/domain_conf.c                        | 53 ++++++++++++++-
>   src/conf/domain_conf.h                        |  3 +
>   src/conf/domain_validate.c                    | 39 +++++++++++
>   src/qemu/qemu_alias.c                         |  1 +
>   src/qemu/qemu_command.c                       |  1 +
>   src/qemu/qemu_domain.c                        | 10 +++
>   src/qemu/qemu_domain_address.c                | 37 ++++++++---
>   src/qemu/qemu_validate.c                      |  8 +++
>   src/security/security_apparmor.c              |  1 +
>   src/security/security_dac.c                   |  2 +
>   src/security/security_selinux.c               |  2 +
>   tests/domaincapsmock.c                        |  9 +++
>   .../memory-hotplug-virtio-mem.xml             | 66 +++++++++++++++++++
>   ...emory-hotplug-virtio-mem.x86_64-latest.xml |  1 +
>   tests/qemuxml2xmltest.c                       |  1 +
>   17 files changed, 264 insertions(+), 16 deletions(-)
>   create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml
>   create mode 120000 tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_64-latest.xml
> 
> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> index af540391db..2938758ec2 100644
> --- a/docs/formatdomain.rst
> +++ b/docs/formatdomain.rst
> @@ -7267,6 +7267,18 @@ Example: usage of the memory devices
>            <size unit='KiB'>524288</size>
>          </target>
>        </memory>
> +     <memory model='virtio-mem'>
> +       <source>
> +         <nodemask>1-3</nodemask>
> +         <pagesize unit='KiB'>2048</pagesize>
> +       </source>
> +       <target>
> +         <size unit='KiB'>2097152</size>
> +         <node>0</node>
> +         <block unit='KiB'>2048</block>
> +         <requested unit='KiB'>1048576</requested>
> +       </target>
> +     </memory>
>      </devices>
>      ...
>   
> @@ -7274,7 +7286,8 @@ Example: usage of the memory devices
>      Provide ``dimm`` to add a virtual DIMM module to the guest. :since:`Since
>      1.2.14` Provide ``nvdimm`` model that adds a Non-Volatile DIMM module.
>      :since:`Since 3.2.0` Provide ``virtio-pmem`` model to add a paravirtualized
> -   persistent memory device. :since:`Since 7.1.0`
> +   persistent memory device. :since:`Since 7.1.0` Provide ``virtio-mem`` model
> +   to add paravirtualized memory device. :since: `Since 7.1.0`
>   
>   ``access``
>      An optional attribute ``access`` ( :since:`since 3.2.0` ) that provides
> @@ -7297,10 +7310,11 @@ Example: usage of the memory devices
>      allowed only for ``model='nvdimm'`` for pSeries guests. :since:`Since 6.2.0`
>   
>   ``source``
> -   For model ``dimm`` this element is optional and allows to fine tune the
> -   source of the memory used for the given memory device. If the element is not
> -   provided defaults configured via ``numatune`` are used. If ``dimm`` is
> -   provided, then the following optional elements can be provided as well:
> +   For model ``dimm`` and model ``virtio-mem`` this element is optional and
> +   allows to fine tune the source of the memory used for the given memory
> +   device. If the element is not provided defaults configured via ``numatune``
> +   are used. If the element is provided, then the following optional elements
> +   can be provided:
>   
>      ``pagesize``
>         This element can be used to override the default host page size used for
> @@ -7366,6 +7380,17 @@ Example: usage of the memory devices
>         so other backend types should use the ``readonly`` element. :since:`Since
>         5.0.0`
>   
> +   ``block``
> +     For ``virtio-mem`` only.
> +     The size of an individual block, granularity of division of memory module.
> +     Must be power of two and at least equal to size of a transparent hugepage
> +     (2MiB on x84_64). The default is hypervisor dependant.

I don't think that 'dependant' is wrong in this context but 'dependent' is more
common.

> +
> +   ``requested``
> +     For ``virtio-mem`` only.
> +     The total size of blocks exposed to the guest. Must respect ``block``
> +     granularity.
> +
>   :anchor:`<a id="elementsIommu"/>`
>   
>   IOMMU devices
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index a4bddcf132..5bc120073e 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -6020,6 +6020,7 @@
>             <value>dimm</value>
>             <value>nvdimm</value>
>             <value>virtio-pmem</value>
> +          <value>virtio-mem</value>
>           </choice>
>         </attribute>
>         <optional>
> @@ -6104,6 +6105,16 @@
>               <ref name="unsignedInt"/>
>             </element>
>           </optional>
> +        <optional>
> +          <element name="block">
> +            <ref name="scaledInteger"/>
> +          </element>
> +        </optional>
> +        <optional>
> +          <element name="requested">
> +            <ref name="scaledInteger"/>
> +          </element>
> +        </optional>
>           <optional>
>             <element name="label">
>               <element name="size">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index dab4f10326..f8c5a40b24 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1310,6 +1310,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel,
>                 "dimm",
>                 "nvdimm",
>                 "virtio-pmem",
> +              "virtio-mem",
>   );
>   
>   VIR_ENUM_IMPL(virDomainShmemModel,
> @@ -5359,6 +5360,7 @@ virDomainMemoryDefPostParse(virDomainMemoryDefPtr mem,
>           }
>           break;
>   
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
> @@ -15322,6 +15324,7 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node,
>   
>       switch (def->model) {
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>           if (virDomainParseMemory("./pagesize", "./pagesize/@unit", ctxt,
>                                    &def->pagesize, false, false) < 0)
>               return -1;
> @@ -15388,7 +15391,8 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
>                                &def->size, true, false) < 0)
>           return -1;
>   
> -    if (def->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) {
> +    switch (def->model) {
> +    case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
>           if (virDomainParseMemory("./label/size", "./label/size/@unit", ctxt,
>                                    &def->labelsize, false, false) < 0)
>               return -1;
> @@ -15407,6 +15411,23 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
>   
>           if (virXPathBoolean("boolean(./readonly)", ctxt))
>               def->readonly = true;
> +        break;
> +
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
> +        if (virDomainParseMemory("./block", "./block/@unit", ctxt,
> +                                 &def->blocksize, false, false) < 0)
> +            return -1;
> +
> +        if (virDomainParseMemory("./requested", "./requested/@unit", ctxt,
> +                                 &def->requestedsize, false, false) < 0)
> +            return -1;
> +        break;
> +
> +    case VIR_DOMAIN_MEMORY_MODEL_NONE:
> +    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
> +    case VIR_DOMAIN_MEMORY_MODEL_LAST:
> +        break;
>       }
>   
>       return 0;
> @@ -17214,11 +17235,14 @@ virDomainMemoryFindByDefInternal(virDomainDefPtr def,
>           /* target info -> always present */
>           if (tmp->model != mem->model ||
>               tmp->targetNode != mem->targetNode ||
> -            tmp->size != mem->size)
> +            tmp->size != mem->size ||
> +            tmp->blocksize != mem->blocksize ||
> +            tmp->requestedsize != mem->requestedsize)
>               continue;
>   
>           switch (mem->model) {
>           case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>               /* source stuff -> match with device */
>               if (tmp->pagesize != mem->pagesize)
>                   continue;
> @@ -22784,6 +22808,22 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDefPtr src,
>           return false;
>       }
>   
> +    if (src->blocksize != dst->blocksize) {
> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                       _("Target memory device block size '%llu' doesn't match "
> +                         "source memory device block size '%llu'"),
> +                       dst->blocksize, src->blocksize);
> +        return false;
> +    }
> +
> +    if (src->requestedsize != dst->requestedsize) {
> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                       _("Target memory device requested size '%llu' doesn't match "
> +                         "source memory device requested size '%llu'"),
> +                       dst->requestedsize, src->requestedsize);
> +        return false;
> +    }
> +
>       if (src->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) {
>           if (src->labelsize != dst->labelsize) {
>               virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> @@ -26507,6 +26547,7 @@ virDomainMemorySourceDefFormat(virBufferPtr buf,
>   
>       switch (def->model) {
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>           if (def->sourceNodes) {
>               if (!(bitmap = virBitmapFormat(def->sourceNodes)))
>                   return -1;
> @@ -26563,6 +26604,14 @@ virDomainMemoryTargetDefFormat(virBufferPtr buf,
>       if (def->readonly)
>           virBufferAddLit(&childBuf, "<readonly/>\n");
>   
> +    if (def->blocksize) {
> +        virBufferAsprintf(&childBuf, "<block unit='KiB'>%llu</block>\n",
> +                          def->blocksize);
> +
> +        virBufferAsprintf(&childBuf, "<requested unit='KiB'>%llu</requested>\n",
> +                          def->requestedsize);
> +    }
> +
>       virXMLFormatElement(buf, "target", NULL, &childBuf);
>   }
>   
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 95ad052891..5d89ecfe9d 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2308,6 +2308,7 @@ typedef enum {
>       VIR_DOMAIN_MEMORY_MODEL_DIMM, /* dimm hotpluggable memory device */
>       VIR_DOMAIN_MEMORY_MODEL_NVDIMM, /* nvdimm memory device */
>       VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM, /* virtio-pmem memory device */
> +    VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM, /* virtio-mem memory device */
>   
>       VIR_DOMAIN_MEMORY_MODEL_LAST
>   } virDomainMemoryModel;
> @@ -2328,6 +2329,8 @@ struct _virDomainMemoryDef {
>       int targetNode;
>       unsigned long long size; /* kibibytes */
>       unsigned long long labelsize; /* kibibytes; valid only for NVDIMM */
> +    unsigned long long blocksize; /* kibibytes; valid only for VIRTIO_MEM */
> +    unsigned long long requestedsize; /* kibibytes; valid only for VIRTIO_MEM */
>       bool readonly; /* valid only for NVDIMM */
>   
>       /* required for QEMU NVDIMM ppc64 support */
> diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
> index 649fc335ac..b5a0c09468 100644
> --- a/src/conf/domain_validate.c
> +++ b/src/conf/domain_validate.c
> @@ -25,6 +25,7 @@
>   #include "virconftypes.h"
>   #include "virlog.h"
>   #include "virutil.h"
> +#include "virhostmem.h"
>   
>   #define VIR_FROM_THIS VIR_FROM_DOMAIN
>   
> @@ -1389,6 +1390,8 @@ static int
>   virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
>                              const virDomainDef *def)
>   {
> +    unsigned long long thpSize;
> +
>       switch (mem->model) {
>       case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
>           if (!mem->nvdimmPath) {
> @@ -1442,6 +1445,42 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
>                              _("virtio-pmem does not support NUMA nodes"));
>               return -1;
>           }
> +        break;
> +
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
> +        if (mem->requestedsize > mem->size) {
> +            virReportError(VIR_ERR_XML_DETAIL, "%s",
> +                           _("requested size must be smaller than @size"));
> +            return -1;
> +        }
> +
> +        if (!VIR_IS_POW2(mem->blocksize)) {
> +            virReportError(VIR_ERR_XML_DETAIL, "%s",
> +                           _("block size must be a power of two"));
> +            return -1;
> +        }
> +
> +        if (virHostMemGetTHPSize(&thpSize) < 0) {
> +            /* We failed to get THP size, fall back to a sane default. On
> +             * almost every architecture the size will be 2MiB, except for some
> +             * funky arches like sparc and m68k. Use 2MiB and refine later if
> +             * somebody complains. */
> +            thpSize = 2048;

FWIW, a Power 9 server uses 2MiB too:

$  cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size
2097152


I don't think you should worry about too much since x86 is the only arch that is
supporting virtio-mem (for now).


Reviewed-by: Daniel Henrique Barboza <danielhb413 at gmail.com>


> +        }
> +
> +        if (mem->blocksize < thpSize) {
> +            virReportError(VIR_ERR_XML_DETAIL,
> +                           _("block size too small, must be at least %lluKiB"),
> +                           thpSize);
> +            return -1;
> +        }
> +
> +        if (mem->requestedsize % mem->blocksize != 0) {
> +            virReportError(VIR_ERR_XML_DETAIL, "%s",
> +                           _("requested size must be an integer multiple of block size"));
> +            return -1;
> +        }
> +        break;
>   
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
>           break;
> diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
> index b3492d6e85..2a4e2393c8 100644
> --- a/src/qemu/qemu_alias.c
> +++ b/src/qemu/qemu_alias.c
> @@ -522,6 +522,7 @@ qemuAssignDeviceMemoryAlias(virDomainDefPtr def,
>       case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
>           prefix = "virtiopmem";
>           break;
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>       default:
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 1ec302d4ac..0a4a8f2646 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -3303,6 +3303,7 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def,
>           device = "virtio-pmem-pci";
>           break;
>   
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>       default:
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 0c078a9388..233adc996f 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -8682,6 +8682,16 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem,
>           needsNuma = false;
>           break;
>   
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
> +        if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
> +            mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                           _("only 'pci' addresses are supported for the %s device"),
> +                           virDomainMemoryModelTypeToString(mem->model));
> +            return -1;
> +        }
> +        break;
> +
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>           return -1;
> diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
> index d40edadb4d..396acc7a09 100644
> --- a/src/qemu/qemu_domain_address.c
> +++ b/src/qemu/qemu_domain_address.c
> @@ -380,9 +380,18 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
>       }
>   
>       for (i = 0; i < def->nmems; i++) {
> -        if (def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM &&
> -            def->mems[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
> -            def->mems[i]->info.type = type;
> +        switch (def->mems[i]->model) {
> +        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
> +        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
> +            if (def->mems[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
> +                def->mems[i]->info.type = type;
> +            break;
> +        case VIR_DOMAIN_MEMORY_MODEL_NONE:
> +        case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +        case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
> +        case VIR_DOMAIN_MEMORY_MODEL_LAST:
> +            break;
> +        }
>       }
>   
>       if (type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
> @@ -1014,6 +1023,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
>       case VIR_DOMAIN_DEVICE_MEMORY:
>           switch (dev->data.memory->model) {
>           case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
> +        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>               return virtioFlags;
>   
>           case VIR_DOMAIN_MEMORY_MODEL_NONE:
> @@ -2441,12 +2451,19 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def,
>       for (i = 0; i < def->nmems; i++) {
>           virDomainMemoryDefPtr mem = def->mems[i];
>   
> -        if (mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM ||
> -            !virDeviceInfoPCIAddressIsWanted(&mem->info))
> -            continue;
> -
> -        if (qemuDomainPCIAddressReserveNextAddr(addrs, &mem->info) < 0)
> -            return -1;
> +        switch (mem->model) {
> +        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
> +        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
> +            if (virDeviceInfoPCIAddressIsWanted(&mem->info) &&
> +                qemuDomainPCIAddressReserveNextAddr(addrs, &mem->info) < 0)
> +                return -1;
> +            break;
> +        case VIR_DOMAIN_MEMORY_MODEL_NONE:
> +        case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +        case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
> +        case VIR_DOMAIN_MEMORY_MODEL_LAST:
> +            break;
> +        }
>       }
>   
>       return 0;
> @@ -3113,6 +3130,7 @@ qemuDomainAssignMemoryDeviceSlot(virQEMUDriverPtr driver,
>           break;
>   
>       case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>           return qemuDomainEnsurePCIAddress(vm, &dev, driver);
>           break;
>   
> @@ -3149,6 +3167,7 @@ qemuDomainAssignMemorySlots(virDomainDefPtr def)
>               break;
>   
>           case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
> +        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>               /* handled in qemuDomainAssignPCIAddresses() */
>               break;
>           case VIR_DOMAIN_MEMORY_MODEL_NONE:
> diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
> index a060bd98ba..0f7c89b972 100644
> --- a/src/qemu/qemu_validate.c
> +++ b/src/qemu/qemu_validate.c
> @@ -4632,6 +4632,14 @@ qemuValidateDomainDeviceDefMemory(virDomainMemoryDefPtr mem,
>           }
>           break;
>   
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
> +        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI)) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                           _("virtio-mem isn't supported by this QEMU binary"));
> +            return -1;
> +        }
> +        break;
> +
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>           break;
> diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
> index 1f309c0c9f..60ffc814d8 100644
> --- a/src/security/security_apparmor.c
> +++ b/src/security/security_apparmor.c
> @@ -693,6 +693,7 @@ AppArmorSetMemoryLabel(virSecurityManagerPtr mgr,
>           return reload_profile(mgr, def, mem->nvdimmPath, true);
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>           break;
>       }
> diff --git a/src/security/security_dac.c b/src/security/security_dac.c
> index 71d58758c4..118d9961dc 100644
> --- a/src/security/security_dac.c
> +++ b/src/security/security_dac.c
> @@ -1894,6 +1894,7 @@ virSecurityDACRestoreMemoryLabel(virSecurityManagerPtr mgr,
>           break;
>   
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>           ret = 0;
> @@ -2077,6 +2078,7 @@ virSecurityDACSetMemoryLabel(virSecurityManagerPtr mgr,
>           break;
>   
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>           ret = 0;
> diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
> index 3563dbfb86..b6744efcd3 100644
> --- a/src/security/security_selinux.c
> +++ b/src/security/security_selinux.c
> @@ -1584,6 +1584,7 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManagerPtr mgr,
>   
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>           break;
>       }
> @@ -1611,6 +1612,7 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManagerPtr mgr,
>           break;
>   
>       case VIR_DOMAIN_MEMORY_MODEL_DIMM:
> +    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
>       case VIR_DOMAIN_MEMORY_MODEL_NONE:
>       case VIR_DOMAIN_MEMORY_MODEL_LAST:
>           ret = 0;
> diff --git a/tests/domaincapsmock.c b/tests/domaincapsmock.c
> index d81a898dc0..34a2f9ad81 100644
> --- a/tests/domaincapsmock.c
> +++ b/tests/domaincapsmock.c
> @@ -17,6 +17,7 @@
>   #include <config.h>
>   
>   #include "virhostcpu.h"
> +#include "virhostmem.h"
>   #ifdef WITH_LIBXL
>   # include "libxl/libxl_capabilities.h"
>   #endif
> @@ -40,3 +41,11 @@ virHostCPUGetMicrocodeVersion(virArch hostArch G_GNUC_UNUSED)
>   {
>       return 0;
>   }
> +
> +int
> +virHostMemGetTHPSize(unsigned long long *size)
> +{
> +    /* Pretend Transparent Huge Page size is 2MiB. */
> +    *size = 2048;
> +    return 0;
> +}
> diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml
> new file mode 100644
> index 0000000000..7c9db0c808
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml
> @@ -0,0 +1,66 @@
> +<domain type='kvm'>
> +  <name>QEMUGuest1</name>
> +  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
> +  <maxMemory slots='16' unit='KiB'>1099511627776</maxMemory>
> +  <memory unit='KiB'>8388608</memory>
> +  <currentMemory unit='KiB'>8388608</currentMemory>
> +  <vcpu placement='static' cpuset='0-1'>2</vcpu>
> +  <os>
> +    <type arch='x86_64' machine='pc'>hvm</type>
> +    <boot dev='hd'/>
> +  </os>
> +  <cpu mode='custom' match='exact' check='none'>
> +    <model fallback='forbid'>qemu64</model>
> +    <topology sockets='2' dies='1' cores='1' threads='1'/>
> +    <numa>
> +      <cell id='0' cpus='0-1' memory='2095104' unit='KiB'/>
> +    </numa>
> +  </cpu>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>destroy</on_crash>
> +  <devices>
> +    <emulator>/usr/bin/qemu-system-i386</emulator>
> +    <disk type='block' device='disk'>
> +      <driver name='qemu' type='raw'/>
> +      <source dev='/dev/HostVG/QEMUGuest1'/>
> +      <target dev='hda' bus='ide'/>
> +      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
> +    </disk>
> +    <controller type='ide' index='0'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
> +    </controller>
> +    <controller type='usb' index='0' model='piix3-uhci'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> +    </controller>
> +    <controller type='pci' index='0' model='pci-root'/>
> +    <input type='mouse' bus='ps2'/>
> +    <input type='keyboard' bus='ps2'/>
> +    <memballoon model='virtio'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
> +    </memballoon>
> +    <memory model='virtio-mem'>
> +      <target>
> +        <size unit='KiB'>1048576</size>
> +        <node>0</node>
> +        <block unit='KiB'>2048</block>
> +        <requested unit='KiB'>524288</requested>
> +      </target>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> +    </memory>
> +    <memory model='virtio-mem'>
> +      <source>
> +        <nodemask>1-3</nodemask>
> +        <pagesize unit='KiB'>2048</pagesize>
> +      </source>
> +      <target>
> +        <size unit='KiB'>2097152</size>
> +        <node>0</node>
> +        <block unit='KiB'>2048</block>
> +        <requested unit='KiB'>1048576</requested>
> +      </target>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
> +    </memory>
> +  </devices>
> +</domain>
> diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_64-latest.xml b/tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_64-latest.xml
> new file mode 120000
> index 0000000000..a9d298129c
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_64-latest.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/memory-hotplug-virtio-mem.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
> index 9553a8a4f8..ba23fdda00 100644
> --- a/tests/qemuxml2xmltest.c
> +++ b/tests/qemuxml2xmltest.c
> @@ -1262,6 +1262,7 @@ mymain(void)
>                    QEMU_CAPS_DEVICE_NVDIMM,
>                    QEMU_CAPS_LAST);
>       DO_TEST_CAPS_LATEST("memory-hotplug-virtio-pmem");
> +    DO_TEST_CAPS_LATEST("memory-hotplug-virtio-mem");
>   
>       DO_TEST("net-udp", NONE);
>   
> 




More information about the libvir-list mailing list