The _virDomainMemoryDef struct is getting a bit messy. It has
various members and only some of them are valid for given model.
Worse, some are re-used for different models. We tried to make
this more bearable by putting a comment next to each member
describing what models the member is valid for, but that gets
messy too.

Therefore, do what we do elsewhere: introduce an union of structs
and move individual members into their respective groups.

This allows us to shorten some names (e.g. nvdimmPath or
sourceNodes) as their purpose is obvious due to their placement.
But to make this commit as small as possible, that'll be
addressed later.

Signed-off-by: Michal Privoznik <mpriv...@redhat.com>
---
 src/conf/domain_conf.c           | 125 +++++++++++++++++++++++--------
 src/conf/domain_conf.h           |  29 +++++--
 src/conf/domain_validate.c       |   4 +-
 src/qemu/qemu_cgroup.c           |  12 ++-
 src/qemu/qemu_command.c          |  97 ++++++++++++++++++------
 src/qemu/qemu_hotplug.c          |  10 +--
 src/qemu/qemu_namespace.c        |   4 +-
 src/qemu/qemu_process.c          |  10 ++-
 src/qemu/qemu_validate.c         |   4 +-
 src/security/security_apparmor.c |  24 ++++--
 src/security/security_dac.c      |   9 ++-
 src/security/security_selinux.c  |  52 ++++++-------
 src/security/virt-aa-helper.c    |   5 +-
 13 files changed, 272 insertions(+), 113 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9a4a26d875..a1dad679dd 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3490,8 +3490,27 @@ void virDomainMemoryDefFree(virDomainMemoryDef *def)
     if (!def)
         return;
 
-    g_free(def->nvdimmPath);
-    virBitmapFree(def->sourceNodes);
+    switch (def->model) {
+    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        virBitmapFree(def->source.dimm.sourceNodes);
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        g_free(def->source.nvdimm.nvdimmPath);
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+        g_free(def->source.virtio_pmem.nvdimmPath);
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+        virBitmapFree(def->source.dimm.sourceNodes);
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+        virBitmapFree(def->source.sgx_epc.sourceNodes);
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_NONE:
+    case VIR_DOMAIN_MEMORY_MODEL_LAST:
+        break;
+    }
+
     g_free(def->uuid);
     virDomainDeviceInfoClear(&def->info);
     g_free(def);
@@ -13267,22 +13286,33 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node,
 {
     VIR_XPATH_NODE_AUTORESTORE(ctxt)
     g_autofree char *nodemask = NULL;
+    unsigned long long *pagesize;
+    virBitmap **sourceNodes = NULL;
 
     ctxt->node = node;
 
     switch (def->model) {
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+
+        if (def->model == VIR_DOMAIN_MEMORY_MODEL_DIMM) {
+            pagesize = &def->source.dimm.pagesize;
+            sourceNodes = &def->source.dimm.sourceNodes;
+        } else {
+            pagesize = &def->source.virtio_mem.pagesize;
+            sourceNodes = &def->source.virtio_mem.sourceNodes;
+        }
+
         if (virDomainParseMemory("./pagesize", "./pagesize/@unit", ctxt,
-                                 &def->pagesize, false, false) < 0)
+                                 pagesize, false, false) < 0)
             return -1;
 
         if ((nodemask = virXPathString("string(./nodemask)", ctxt))) {
-            if (virBitmapParse(nodemask, &def->sourceNodes,
+            if (virBitmapParse(nodemask, sourceNodes,
                                VIR_DOMAIN_CPUMASK_LEN) < 0)
                 return -1;
 
-            if (virBitmapIsAllClear(def->sourceNodes)) {
+            if (virBitmapIsAllClear(*sourceNodes)) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                _("Invalid value of 'nodemask': %1$s"), 
nodemask);
                 return -1;
@@ -13291,28 +13321,28 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node,
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
-        def->nvdimmPath = virXPathString("string(./path)", ctxt);
+        def->source.nvdimm.nvdimmPath = virXPathString("string(./path)", ctxt);
 
         if (virDomainParseMemory("./alignsize", "./alignsize/@unit", ctxt,
-                                 &def->alignsize, false, false) < 0)
+                                 &def->source.nvdimm.alignsize, false, false) 
< 0)
             return -1;
 
         if (virXPathBoolean("boolean(./pmem)", ctxt))
-            def->nvdimmPmem = true;
+            def->source.nvdimm.nvdimmPmem = true;
 
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        def->nvdimmPath = virXPathString("string(./path)", ctxt);
+        def->source.virtio_pmem.nvdimmPath = virXPathString("string(./path)", 
ctxt);
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
         if ((nodemask = virXPathString("string(./nodemask)", ctxt))) {
-            if (virBitmapParse(nodemask, &def->sourceNodes,
+            if (virBitmapParse(nodemask, &def->source.sgx_epc.sourceNodes,
                                VIR_DOMAIN_CPUMASK_LEN) < 0)
                 return -1;
 
-            if (virBitmapIsAllClear(def->sourceNodes)) {
+            if (virBitmapIsAllClear(def->source.sgx_epc.sourceNodes)) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                _("Invalid value of 'nodemask': %1$s"), 
nodemask);
                 return -1;
@@ -15260,27 +15290,36 @@ virDomainMemoryFindByDefInternal(virDomainDef *def,
 
         switch (mem->model) {
         case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+            if (tmp->source.dimm.pagesize != mem->source.dimm.pagesize)
+                continue;
+
+            if (!virBitmapEqual(tmp->source.dimm.sourceNodes,
+                                mem->source.dimm.sourceNodes))
+                continue;
+            break;
         case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
-            /* source stuff -> match with device */
-            if (tmp->pagesize != mem->pagesize)
+            if (tmp->source.virtio_mem.pagesize != 
mem->source.virtio_mem.pagesize)
                 continue;
 
-            if (!virBitmapEqual(tmp->sourceNodes, mem->sourceNodes))
+            if (!virBitmapEqual(tmp->source.virtio_mem.sourceNodes,
+                                mem->source.virtio_mem.sourceNodes))
                 continue;
             break;
 
         case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
-            if (STRNEQ(tmp->nvdimmPath, mem->nvdimmPath))
+            if (STRNEQ(tmp->source.nvdimm.nvdimmPath, 
mem->source.nvdimm.nvdimmPath))
                 continue;
             break;
 
         case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-            if (STRNEQ(tmp->nvdimmPath, mem->nvdimmPath))
+            if (STRNEQ(tmp->source.virtio_pmem.nvdimmPath,
+                       mem->source.virtio_pmem.nvdimmPath))
                 continue;
             break;
 
         case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
-            if (!virBitmapEqual(tmp->sourceNodes, mem->sourceNodes))
+            if (!virBitmapEqual(tmp->source.sgx_epc.sourceNodes,
+                                mem->source.sgx_epc.sourceNodes))
                 continue;
             break;
 
@@ -21004,7 +21043,8 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef 
*src,
         return false;
     }
 
-    if (src->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) {
+    switch (src->model) {
+    case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
         if (src->labelsize != dst->labelsize) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("Target NVDIMM label size '%1$llu' doesn't match 
source NVDIMM label size '%2$llu'"),
@@ -21012,14 +21052,15 @@ 
virDomainMemoryDefCheckABIStability(virDomainMemoryDef *src,
             return false;
         }
 
-        if (src->alignsize != dst->alignsize) {
+        if (src->source.nvdimm.alignsize != dst->source.nvdimm.alignsize) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("Target NVDIMM alignment '%1$llu' doesn't match 
source NVDIMM alignment '%2$llu'"),
-                           src->alignsize, dst->alignsize);
+                           src->source.nvdimm.alignsize,
+                           dst->source.nvdimm.alignsize);
             return false;
         }
 
-        if (src->nvdimmPmem != dst->nvdimmPmem) {
+        if (src->source.nvdimm.nvdimmPmem != dst->source.nvdimm.nvdimmPmem) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("Target NVDIMM pmem flag doesn't match "
                              "source NVDIMM pmem flag"));
@@ -21040,6 +21081,15 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef 
*src,
                            _("Target NVDIMM UUID doesn't match source 
NVDIMM"));
             return false;
         }
+        break;
+
+    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+    case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+    case VIR_DOMAIN_MEMORY_MODEL_NONE:
+    case VIR_DOMAIN_MEMORY_MODEL_LAST:
+        break;
     }
 
     return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
@@ -25097,37 +25147,48 @@ virDomainMemorySourceDefFormat(virBuffer *buf,
 
     switch (def->model) {
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        if (def->source.dimm.sourceNodes) {
+            if (!(bitmap = virBitmapFormat(def->source.dimm.sourceNodes)))
+                return -1;
+
+            virBufferAsprintf(&childBuf, "<nodemask>%s</nodemask>\n", bitmap);
+        }
+
+        if (def->source.dimm.pagesize)
+            virBufferAsprintf(&childBuf, "<pagesize 
unit='KiB'>%llu</pagesize>\n",
+                              def->source.dimm.pagesize);
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
-        if (def->sourceNodes) {
-            if (!(bitmap = virBitmapFormat(def->sourceNodes)))
+        if (def->source.virtio_mem.sourceNodes) {
+            if (!(bitmap = 
virBitmapFormat(def->source.virtio_mem.sourceNodes)))
                 return -1;
 
             virBufferAsprintf(&childBuf, "<nodemask>%s</nodemask>\n", bitmap);
         }
 
-        if (def->pagesize)
+        if (def->source.virtio_mem.pagesize)
             virBufferAsprintf(&childBuf, "<pagesize 
unit='KiB'>%llu</pagesize>\n",
-                              def->pagesize);
+                              def->source.virtio_mem.pagesize);
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
-        virBufferEscapeString(&childBuf, "<path>%s</path>\n", def->nvdimmPath);
+        virBufferEscapeString(&childBuf, "<path>%s</path>\n", 
def->source.nvdimm.nvdimmPath);
 
-        if (def->alignsize)
+        if (def->source.nvdimm.alignsize)
             virBufferAsprintf(&childBuf, "<alignsize 
unit='KiB'>%llu</alignsize>\n",
-                              def->alignsize);
+                              def->source.nvdimm.alignsize);
 
-        if (def->nvdimmPmem)
+        if (def->source.nvdimm.nvdimmPmem)
             virBufferAddLit(&childBuf, "<pmem/>\n");
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        virBufferEscapeString(&childBuf, "<path>%s</path>\n", def->nvdimmPath);
+        virBufferEscapeString(&childBuf, "<path>%s</path>\n", 
def->source.virtio_pmem.nvdimmPath);
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
-        if (def->sourceNodes) {
-            if (!(bitmap = virBitmapFormat(def->sourceNodes)))
+        if (def->source.sgx_epc.sourceNodes) {
+            if (!(bitmap = virBitmapFormat(def->source.sgx_epc.sourceNodes)))
                 return -1;
 
             virBufferAsprintf(&childBuf, "<nodemask>%s</nodemask>\n", bitmap);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index c857ba556f..8770547590 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2634,18 +2634,33 @@ typedef enum {
 } virDomainMemoryModel;
 
 struct _virDomainMemoryDef {
+    virDomainMemoryModel model;
     virDomainMemoryAccess access;
     virTristateBool discard;
 
-    /* source */
-    virBitmap *sourceNodes;
-    unsigned long long pagesize; /* kibibytes */
-    char *nvdimmPath; /* valid for NVDIMM an VIRTIO_PMEM */
-    unsigned long long alignsize; /* kibibytes; valid only for NVDIMM */
-    bool nvdimmPmem; /* valid only for NVDIMM */
+    union {
+        struct {
+            unsigned long long pagesize; /* kibibytes */
+            virBitmap *sourceNodes;
+        } dimm;
+        struct {
+            char *nvdimmPath;
+            bool nvdimmPmem;
+            unsigned long long alignsize; /* kibibytes */
+        } nvdimm;
+        struct {
+            char *nvdimmPath;
+        } virtio_pmem;
+        struct {
+            unsigned long long pagesize; /* kibibytes */
+            virBitmap *sourceNodes;
+        } virtio_mem;
+        struct {
+            virBitmap *sourceNodes;
+        } sgx_epc;
+    } source;
 
     /* target */
-    virDomainMemoryModel model;
     int targetNode;
     unsigned long long size; /* kibibytes */
     unsigned long long labelsize; /* kibibytes; valid only for NVDIMM */
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index ad383b604e..2832fd010e 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2260,7 +2260,7 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
 
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
-        if (!mem->nvdimmPath) {
+        if (!mem->source.nvdimm.nvdimmPath) {
             virReportError(VIR_ERR_XML_DETAIL, "%s",
                            _("path is required for model 'nvdimm'"));
             return -1;
@@ -2286,7 +2286,7 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        if (!mem->nvdimmPath) {
+        if (!mem->source.virtio_pmem.nvdimmPath) {
             virReportError(VIR_ERR_XML_DETAIL,
                            _("path is required for model '%1$s'"),
                            virDomainMemoryModelTypeToString(mem->model));
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index fe78a0251a..b9d893fd86 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -553,8 +553,12 @@ qemuSetupMemoryDevicesCgroup(virDomainObj *vm,
 
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        if (qemuCgroupAllowDevicePath(vm, mem->source.nvdimm.nvdimmPath,
+                                      VIR_CGROUP_DEVICE_RW, false) < 0)
+            return -1;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        if (qemuCgroupAllowDevicePath(vm, mem->nvdimmPath,
+        if (qemuCgroupAllowDevicePath(vm, mem->source.virtio_pmem.nvdimmPath,
                                       VIR_CGROUP_DEVICE_RW, false) < 0)
             return -1;
         break;
@@ -587,8 +591,12 @@ qemuTeardownMemoryDevicesCgroup(virDomainObj *vm,
 
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        if (qemuCgroupDenyDevicePath(vm, mem->source.nvdimm.nvdimmPath,
+                                     VIR_CGROUP_DEVICE_RWM, false) < 0)
+            return -1;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        if (qemuCgroupDenyDevicePath(vm, mem->nvdimmPath,
+        if (qemuCgroupDenyDevicePath(vm, mem->source.virtio_pmem.nvdimmPath,
                                      VIR_CGROUP_DEVICE_RWM, false) < 0)
             return -1;
         break;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 77c5335bde..2e06261ef2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3146,11 +3146,34 @@ qemuBuildMemoryGetPagesize(virQEMUDriverConfig *cfg,
                            bool *preallocRet)
 {
     const long system_page_size = virGetSystemPageSizeKB();
-    unsigned long long pagesize = mem->pagesize;
-    bool needHugepage = !!pagesize;
-    bool useHugepage = !!pagesize;
+    unsigned long long pagesize = 0;
+    const char *nvdimmPath = NULL;
+    bool needHugepage = false;
+    bool useHugepage = false;
     bool prealloc = false;
 
+    switch (mem->model) {
+    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        pagesize = mem->source.dimm.pagesize;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+        pagesize = mem->source.virtio_mem.pagesize;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        nvdimmPath = mem->source.nvdimm.nvdimmPath;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+        nvdimmPath = mem->source.virtio_pmem.nvdimmPath;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+    case VIR_DOMAIN_MEMORY_MODEL_NONE:
+    case VIR_DOMAIN_MEMORY_MODEL_LAST:
+        break;
+    }
+
+    needHugepage = !!pagesize;
+    useHugepage = !!pagesize;
+
     if (pagesize == 0) {
         virDomainHugePage *master_hugepage = NULL;
         virDomainHugePage *hugepage = NULL;
@@ -3216,10 +3239,11 @@ qemuBuildMemoryGetPagesize(virQEMUDriverConfig *cfg,
     /* If the NVDIMM is a real device then there's nothing to prealloc.
      * If anything, we would be only wearing off the device.
      * Similarly, virtio-pmem-pci doesn't need prealloc either. */
-    if (mem->nvdimmPath) {
-        if (!mem->nvdimmPmem &&
-            mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM)
+    if (nvdimmPath) {
+        if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM &&
+            !mem->source.nvdimm.nvdimmPmem) {
             prealloc = true;
+        }
     } else if (useHugepage) {
         prealloc = true;
     }
@@ -3286,6 +3310,8 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
     unsigned long long pagesize = 0;
     bool needHugepage = false;
     bool useHugepage = false;
+    bool hasSourceNodes = false;
+    const char *nvdimmPath = NULL;
     int discard = mem->discard;
     bool disableCanonicalPath = false;
 
@@ -3324,12 +3350,36 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
 
     props = virJSONValueNewObject();
 
+    switch (mem->model) {
+    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        nodemask = mem->source.dimm.sourceNodes;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+        nodemask = mem->source.virtio_mem.sourceNodes;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+        nodemask = mem->source.sgx_epc.sourceNodes;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        nvdimmPath = mem->source.nvdimm.nvdimmPath;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+        nvdimmPath = mem->source.virtio_pmem.nvdimmPath;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_NONE:
+    case VIR_DOMAIN_MEMORY_MODEL_LAST:
+        break;
+    }
+
+    hasSourceNodes = !!nodemask;
+
     if (mem->model == VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) {
         backendType = "memory-backend-epc";
         if (!priv->memPrealloc)
             prealloc = true;
-    } else if (!mem->nvdimmPath &&
-        def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_MEMFD) {
+
+    } else if (!nvdimmPath &&
+               def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_MEMFD) {
         backendType = "memory-backend-memfd";
 
         if (useHugepage &&
@@ -3343,11 +3393,11 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
 
         if (systemMemory)
             disableCanonicalPath = true;
-    } else if (useHugepage || mem->nvdimmPath || memAccess ||
-        def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) {
+    } else if (useHugepage || nvdimmPath || memAccess ||
+               def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) {
 
-        if (mem->nvdimmPath) {
-            memPath = g_strdup(mem->nvdimmPath);
+        if (nvdimmPath) {
+            memPath = g_strdup(nvdimmPath);
         } else if (useHugepage) {
             if (qemuGetDomainHupageMemPath(priv->driver, def, pagesize, 
&memPath) < 0)
                 return -1;
@@ -3363,7 +3413,7 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
                                   NULL) < 0)
             return -1;
 
-        if (!mem->nvdimmPath &&
+        if (!nvdimmPath &&
             virJSONValueObjectAdd(&props,
                                   "T:discard-data", discard,
                                   NULL) < 0) {
@@ -3423,10 +3473,13 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
     if (virJSONValueObjectAdd(&props, "U:size", mem->size * 1024, NULL) < 0)
         return -1;
 
-    if (virJSONValueObjectAdd(&props, "P:align", mem->alignsize * 1024, NULL) 
< 0)
+    if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM &&
+        virJSONValueObjectAdd(&props, "P:align",
+                              mem->source.nvdimm.alignsize * 1024, NULL) < 0)
         return -1;
 
-    if (mem->nvdimmPmem) {
+    if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM &&
+        mem->source.nvdimm.nvdimmPmem) {
         if (!virQEMUCapsGet(priv->qemuCaps, 
QEMU_CAPS_OBJECT_MEMORY_FILE_PMEM)) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("nvdimm pmem property is not available "
@@ -3437,12 +3490,10 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
             return -1;
     }
 
-    if (mem->sourceNodes) {
-        nodemask = mem->sourceNodes;
-    } else {
-        if (virDomainNumatuneMaybeGetNodeset(def->numa, priv->autoNodeset,
-                                             &nodemask, mem->targetNode) < 0)
-            return -1;
+    if (!hasSourceNodes &&
+        virDomainNumatuneMaybeGetNodeset(def->numa, priv->autoNodeset,
+                                         &nodemask, mem->targetNode) < 0) {
+        return -1;
     }
 
     if (nodemask) {
@@ -3466,8 +3517,8 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
     }
 
     /* If none of the following is requested... */
-    if (!needHugepage && !mem->sourceNodes && !nodeSpecified &&
-        !mem->nvdimmPath &&
+    if (!needHugepage && !hasSourceNodes && !nodeSpecified &&
+        !nvdimmPath &&
         memAccess == VIR_DOMAIN_MEMORY_ACCESS_DEFAULT &&
         def->mem.source != VIR_DOMAIN_MEMORY_SOURCE_FILE &&
         def->mem.source != VIR_DOMAIN_MEMORY_SOURCE_MEMFD &&
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e5f587ba65..ece5b2598d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -7022,18 +7022,18 @@ qemuDomainChangeMemoryLiveValidateChange(const 
virDomainMemoryDef *oldDef,
         return false;
     }
 
-    if (!virBitmapEqual(oldDef->sourceNodes,
-                        newDef->sourceNodes)) {
+    if (!virBitmapEqual(oldDef->source.virtio_mem.sourceNodes,
+                        newDef->source.virtio_mem.sourceNodes)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("cannot modify memory source nodes"));
         return false;
     }
 
-    if (oldDef->pagesize != newDef->pagesize) {
+    if (oldDef->source.virtio_mem.pagesize != 
newDef->source.virtio_mem.pagesize) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("cannot modify memory pagesize from '%1$llu' to 
'%2$llu'"),
-                       oldDef->pagesize,
-                       newDef->pagesize);
+                       oldDef->source.virtio_mem.pagesize,
+                       newDef->source.virtio_mem.pagesize);
         return false;
     }
 
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 7fa43253b1..206bbd7375 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -372,8 +372,10 @@ qemuDomainSetupMemory(virDomainMemoryDef *mem,
 {
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        *paths = g_slist_prepend(*paths, 
g_strdup(mem->source.nvdimm.nvdimmPath));
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        *paths = g_slist_prepend(*paths, g_strdup(mem->nvdimmPath));
+        *paths = g_slist_prepend(*paths, 
g_strdup(mem->source.virtio_pmem.nvdimmPath));
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0644f80161..aa2593fa9a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3927,11 +3927,15 @@ static bool
 qemuProcessDomainMemoryDefNeedHugepagesPath(const virDomainMemoryDef *mem,
                                             const long system_pagesize)
 {
+    unsigned long long pagesize = 0;
+
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        pagesize = mem->source.dimm.pagesize;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
-        return mem->pagesize && mem->pagesize != system_pagesize;
-
+        pagesize = mem->source.virtio_mem.pagesize;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_NONE:
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
@@ -3941,7 +3945,7 @@ qemuProcessDomainMemoryDefNeedHugepagesPath(const 
virDomainMemoryDef *mem,
         return false;
     }
 
-    return false;
+    return pagesize != 0 && pagesize != system_pagesize;
 }
 
 
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index d5c2b2cd44..9b548ee515 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -5074,8 +5074,8 @@ qemuValidateDomainDeviceDefMemory(virDomainMemoryDef *mem,
             return -1;
         }
 
-        if (mem->sourceNodes) {
-            while ((node = virBitmapNextSetBit(mem->sourceNodes, node)) >= 0) {
+        if (mem->source.sgx_epc.sourceNodes) {
+            while ((node = 
virBitmapNextSetBit(mem->source.sgx_epc.sourceNodes, node)) >= 0) {
                 if (mem->size > sgxCaps->sgxSections[node].size) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                    _("sgx epc size %1$lld on host node %2$zd 
is less than requested size %3$lld"),
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 5752cd422d..4b904500ff 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -638,16 +638,15 @@ AppArmorSetMemoryLabel(virSecurityManager *mgr,
                        virDomainDef *def,
                        virDomainMemoryDef *mem)
 {
+    const char *path = NULL;
+
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        path = mem->source.nvdimm.nvdimmPath;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        if (!virFileExists(mem->nvdimmPath)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("%1$s: \'%2$s\' does not exist"),
-                           __func__, mem->nvdimmPath);
-            return -1;
-        }
-        return reload_profile(mgr, def, mem->nvdimmPath, true);
+        path = mem->source.virtio_pmem.nvdimmPath;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_NONE:
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
@@ -656,7 +655,16 @@ AppArmorSetMemoryLabel(virSecurityManager *mgr,
         break;
     }
 
-    return 0;
+    if (!path)
+        return 0;
+
+    if (!virFileExists(path)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("%1$s: \'%2$s\' does not exist"),
+                       __func__, path);
+        return -1;
+    }
+    return reload_profile(mgr, def, path, true);
 }
 
 
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index c7dc145621..a615c6b09e 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1857,8 +1857,9 @@ virSecurityDACRestoreMemoryLabel(virSecurityManager *mgr,
 {
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        return virSecurityDACRestoreFileLabel(mgr, 
mem->source.nvdimm.nvdimmPath);
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        return virSecurityDACRestoreFileLabel(mgr, mem->nvdimmPath);
+        return virSecurityDACRestoreFileLabel(mgr, 
mem->source.virtio_pmem.nvdimmPath);
 
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
         /* We set label on SGX /dev nodes iff running with namespaces, so we
@@ -2044,9 +2045,13 @@ virSecurityDACSetMemoryLabel(virSecurityManager *mgr,
 
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        return virSecurityDACSetOwnership(mgr, NULL,
+                                          mem->source.nvdimm.nvdimmPath,
+                                          user, group, true);
+
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
         return virSecurityDACSetOwnership(mgr, NULL,
-                                          mem->nvdimmPath,
+                                          mem->source.virtio_pmem.nvdimmPath,
                                           user, group, true);
 
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index e3e6a6115f..fdbfd5495f 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1610,24 +1610,20 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManager 
*mgr,
                                  virDomainMemoryDef *mem)
 {
     virSecurityLabelDef *seclabel;
+    const char *path = NULL;
+
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (!seclabel || !seclabel->relabel)
+        return 0;
 
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        path = mem->source.nvdimm.nvdimmPath;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
-        if (!seclabel || !seclabel->relabel)
-            return 0;
-
-        if (virSecuritySELinuxSetFilecon(mgr, mem->nvdimmPath,
-                                         seclabel->imagelabel, true) < 0)
-            return -1;
+        path = mem->source.virtio_pmem.nvdimmPath;
         break;
-
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
-        seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
-        if (!seclabel || !seclabel->relabel)
-            return 0;
-
         if (virSecuritySELinuxSetFilecon(mgr, DEV_SGX_VEPC,
                                          seclabel->imagelabel, true) < 0 ||
             virSecuritySELinuxSetFilecon(mgr, DEV_SGX_PROVISION,
@@ -1642,6 +1638,12 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManager *mgr,
         break;
     }
 
+    if (!path)
+        return 0;
+
+    if (virSecuritySELinuxSetFilecon(mgr, path,
+                                     seclabel->imagelabel, true) < 0)
+        return -1;
     return 0;
 }
 
@@ -1653,36 +1655,36 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManager 
*mgr,
 {
     int ret = -1;
     virSecurityLabelDef *seclabel;
+    const char *path = NULL;
+
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (!seclabel || !seclabel->relabel)
+        return 0;
 
     switch (mem->model) {
     case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        path = mem->source.nvdimm.nvdimmPath;
+        break;
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-        seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
-        if (!seclabel || !seclabel->relabel)
-            return 0;
-
-        ret = virSecuritySELinuxRestoreFileLabel(mgr, mem->nvdimmPath, true);
+        path = mem->source.virtio_pmem.nvdimmPath;
         break;
-
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
-        seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
-        if (!seclabel || !seclabel->relabel)
-            return 0;
-
         ret = virSecuritySELinuxRestoreFileLabel(mgr, DEV_SGX_VEPC, true);
         if (virSecuritySELinuxRestoreFileLabel(mgr, DEV_SGX_PROVISION, true) < 
0)
             ret = -1;
-        break;
+        return ret;
 
     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;
         break;
     }
 
-    return ret;
+    if (!path)
+        return 0;
+
+    return virSecuritySELinuxRestoreFileLabel(mgr, path, true);
 }
 
 
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 23e3dba7f5..bf368cac47 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1151,8 +1151,11 @@ get_files(vahControl * ctl)
 
         switch (mem->model) {
         case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+            if (vah_add_file(&buf, mem->source.nvdimm.nvdimmPath, "rw") != 0)
+                goto cleanup;
+            break;
         case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-            if (vah_add_file(&buf, mem->nvdimmPath, "rw") != 0)
+            if (vah_add_file(&buf, mem->source.virtio_pmem.nvdimmPath, "rw") 
!= 0)
                 goto cleanup;
             break;
         case VIR_DOMAIN_MEMORY_MODEL_DIMM:
-- 
2.41.0

Reply via email to