]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Introduce <address/> for virtio-mem and virtio-pmem
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 28 Mar 2023 08:39:55 +0000 (10:39 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 26 May 2023 14:44:42 +0000 (16:44 +0200)
Both virtio-mem and virtio-pmem devices have '.memaddr' attribute
which controls the address where they are mapped in the guest
memory. Ideally, users do not need to specify this as QEMU does
the right thing and computes addresses automatically on startup.

But soon, we will need to record this address as it is part of
guest ABI. And also, there might be some users that want to
control this value. Now, we are in a bit of a pickle, because
both these device types already have a PCI address, therefore we
can't just use <address/> blindly. But what we can do, is
introduce <address/> under the <target/> element. This is also
more conceptual, as knobs under <target/> control guest visible
config of memory device (and .memaddr surely falls into that
category).

NB, SgxEPCDeviceInfo struct in QMP definition also has .memaddr
attribute, but because of the way we build cmd line there's no
(easy) way to set the attribute. So ignore that for now.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
docs/formatdomain.rst
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/domain_validate.c
src/conf/schemas/domaincommon.rng
tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml
tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.xml

index dd28a565e15aa0fcac828f7d87caabcc25ac5f88..c3526439bfbf4353dd8ed15d696b63efc0d3d7dd 100644 (file)
@@ -8129,6 +8129,7 @@ Example: usage of the memory devices
        </source>
        <target>
          <size unit='KiB'>524288</size>
+         <address base='0x140000000'/>
        </target>
      </memory>
      <memory model='virtio-mem'>
@@ -8142,6 +8143,7 @@ Example: usage of the memory devices
          <block unit='KiB'>2048</block>
          <requested unit='KiB'>1048576</requested>
          <current unit='KiB'>524288</current>
+         <address base='0x150000000'/>
        </target>
      </memory>
      <memory model='sgx-epc'>
@@ -8285,6 +8287,11 @@ Example: usage of the memory devices
      element is formatted into live XML and never parsed, i.e. it is
      output-only element.
 
+   ``address``
+     For ``virtio-mem`` and ``virtio-pmem`` only.
+     The physical address in memory, where device is mapped. :since:`Since
+     9.4.0`
+
 
 IOMMU devices
 ~~~~~~~~~~~~~
index 6a864a8db9e7db999ab73dd0d5f8ecf95cfa1f79..e7226c5f9933aa479446192e264348dcac9ac450 100644 (file)
@@ -13318,6 +13318,7 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
                                  virDomainMemoryDef *def)
 {
     VIR_XPATH_NODE_AUTORESTORE(ctxt)
+    xmlNodePtr addrNode = NULL;
     int rv;
 
     ctxt->node = node;
@@ -13363,16 +13364,27 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
         if (virDomainParseMemory("./requested", "./requested/@unit", ctxt,
                                  &def->requestedsize, false, false) < 0)
             return -1;
+
+        addrNode = virXPathNode("./address", ctxt);
+        break;
+
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+        addrNode = virXPathNode("./address", ctxt);
         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_SGX_EPC:
     case VIR_DOMAIN_MEMORY_MODEL_LAST:
         break;
     }
 
+    if (addrNode &&
+        virXMLPropULongLong(addrNode, "base", 16,
+                            VIR_XML_PROP_NONE, &def->address) < 0) {
+        return -1;
+    }
+
     return 0;
 }
 
@@ -20952,6 +20964,13 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef *src,
         return false;
     }
 
+    if (src->address != dst->address) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target memory device address '0x%1$llx' doesn't match source memory device address '0x%2$llx'"),
+                       dst->address, src->address);
+        return false;
+    }
+
     if (src->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) {
         if (src->labelsize != dst->labelsize) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -25120,6 +25139,9 @@ virDomainMemoryTargetDefFormat(virBuffer *buf,
         }
     }
 
+    if (def->address)
+        virBufferAsprintf(&childBuf, "<address base='0x%llx'/>\n", def->address);
+
     virXMLFormatElement(buf, "target", NULL, &childBuf);
 }
 
index c1cb2ed69d8f1fabbe619b412d8a1fb0ac5b88e8..629e32c39f672f6e3ee0b8c4d98b5e5662611a6b 100644 (file)
@@ -2652,6 +2652,8 @@ struct _virDomainMemoryDef {
     unsigned long long currentsize; /* kibibytes, valid for VIRTIO_MEM and
                                        active domain only, only to report never
                                        parse */
+    unsigned long long address; /* address where memory is mapped, valid for
+                                   VIRTIO_PMEM and VIRTIO_MEM only. */
     bool readonly; /* valid only for NVDIMM */
 
     /* required for QEMU NVDIMM ppc64 support */
index e04b85fee4b4645beff7ac2b4e411ed4d393cd9d..80d6a2ffd9194528298e81489e3129190db3e492 100644 (file)
@@ -2355,6 +2355,12 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
                            _("requested size must be an integer multiple of block size"));
             return -1;
         }
+
+        if (mem->address % mem->blocksize != 0) {
+            virReportError(VIR_ERR_XML_DETAIL, "%s",
+                           _("memory device address must be aligned to blocksize"));
+            return -1;
+        }
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
index f8c7b6a64854004adab12b0504facb51f7dddc63..c1725bb5118ab558b73454b76e7b7d946b9bdda8 100644 (file)
             <empty/>
           </element>
         </optional>
+        <optional>
+          <element name="address">
+            <attribute name="base">
+              <ref name="hexuint"/>
+            </attribute>
+          </element>
+        </optional>
       </interleave>
     </element>
   </define>
index 73036d8602aa7bbe8bb39a03cae553f1379196a7..f5cc4a35ed6e120e93f1ebc5baf7f5c807f66623 100644 (file)
@@ -65,6 +65,7 @@
         <node>0</node>
         <block unit='KiB'>2048</block>
         <requested unit='KiB'>1048576</requested>
+        <address base='0x150000000'/>
       </target>
       <address type='pci' domain='0x0000' bus='0x01' slot='0x01' function='0x0'/>
     </memory>
index 4cebd294ec5f85def34a4dcf7ab9522c3d65ec21..21b90e4d8a45e3e1af32c354834769f067245eda 100644 (file)
@@ -47,6 +47,7 @@
       </source>
       <target>
         <size unit='KiB'>524288</size>
+        <address base='0x140000000'/>
       </target>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
     </memory>