]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add NVRAM device
authorLi Zhang <zhlcindy@linux.vnet.ibm.com>
Fri, 19 Apr 2013 08:37:51 +0000 (16:37 +0800)
committerOsier Yang <jyang@redhat.com>
Thu, 25 Apr 2013 08:50:11 +0000 (16:50 +0800)
For pSeries guest in QEMU, NVRAM is one kind of spapr-vio device.
Users are allowed to specify spapr-vio devices'address.
But NVRAM is not supported in libvirt. So this patch is to
add NVRAM device to allow users to specify its address.

In QEMU, NVRAM device's address is specified by
 "-global spapr-nvram.reg=xxxxx".

In libvirt, XML file is defined as the following:

  <nvram>
    <address type='spapr-vio' reg='0x3000'/>
  </nvram>

Signed-off-by: Li Zhang <zhlcindy@linux.vnet.ibm.com>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h

index f3e3de4c1c46c9953b7cf18e62e37a9461a4170b..6d6cfb6dc44b1c940c59e7326842973b579a4906 100644 (file)
@@ -4506,6 +4506,40 @@ qemu-kvm -net nic,model=? /dev/null
       </dd>
     </dl>
 
+    <h4><a name="elementsNVRAM">NVRAM device</a></h4>
+    <p>
+      nvram device is always added to pSeries guest on PPC64, and its address
+      is allowed to be changed.  Element <code>nvram</code> (only valid for
+      pSeries guest, <span class="since">since 1.0.5</span>) is provided to
+      enable the address setting.
+    </p>
+    <p>
+      Example: usage of NVRAM configuration
+    </p>
+<pre>
+  ...
+  &lt;devices&gt;
+    &lt;nvram&gt;
+      &lt;address type='spapr-vio' reg='0x3000'/&gt;
+    &lt;/nvram&gt;
+  &lt;/devices&gt;
+  ...
+</pre>
+  <dl>
+    <dt><code>spapr-vio</code></dt>
+    <dd>
+      <p>
+        VIO device address type, only valid for PPC64.
+      </p>
+    </dd>
+    <dt><code>reg</code></dt>
+    <dd>
+      <p>
+        Device address
+      </p>
+    </dd>
+  </dl>
+
     <h3><a name="seclabel">Security label</a></h3>
 
     <p>
index a9d05817d9b52f52a0ea2645b8f2e2b72fd73cc0..0c1b76aea0276d052b82d24da31a5034f8784e6e 100644 (file)
       </optional>
     </element>
   </define>
+  <define name="nvram">
+    <element name="nvram">
+      <optional>
+        <ref name="address"/>
+      </optional>
+    </element>
+  </define>
   <define name="memballoon">
     <element name="memballoon">
       <attribute name="model">
         <optional>
           <ref name="memballoon"/>
         </optional>
+        <optional>
+          <ref name="nvram"/>
+        </optional>
       </interleave>
     </element>
   </define>
index 0b432dd3d8dd9dc3030cd736c4ddb18187d88d75..958b77beeee650bed94ad0c197339972da8070b3 100644 (file)
@@ -194,6 +194,7 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
               "smartcard",
               "chr",
               "memballoon",
+              "nvram",
               "rng")
 
 VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
@@ -1560,6 +1561,16 @@ void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def)
     VIR_FREE(def);
 }
 
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def)
+{
+    if (!def)
+        return;
+
+    virDomainDeviceInfoClear(&def->info);
+
+    VIR_FREE(def);
+}
+
 void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def)
 {
     if (!def)
@@ -1743,6 +1754,7 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_CHR:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
+    case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_LAST:
         break;
     }
@@ -1951,6 +1963,7 @@ void virDomainDefFree(virDomainDefPtr def)
     virDomainWatchdogDefFree(def->watchdog);
 
     virDomainMemballoonDefFree(def->memballoon);
+    virDomainNVRAMDefFree(def->nvram);
 
     for (i = 0; i < def->nseclabels; i++)
         virSecurityLabelDefFree(def->seclabels[i]);
@@ -2519,6 +2532,12 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
         if (cb(def, &device, &def->rng->info, opaque) < 0)
             return -1;
     }
+    if (def->nvram) {
+        device.type = VIR_DOMAIN_DEVICE_NVRAM;
+        device.data.nvram = def->nvram;
+        if (cb(def, &device, &def->nvram->info, opaque) < 0)
+            return -1;
+    }
     device.type = VIR_DOMAIN_DEVICE_HUB;
     for (i = 0; i < def->nhubs ; i++) {
         device.data.hub = def->hubs[i];
@@ -2550,6 +2569,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_CHR:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
+    case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_LAST:
     case VIR_DOMAIN_DEVICE_RNG:
         break;
@@ -8138,6 +8158,27 @@ error:
     goto cleanup;
 }
 
+static virDomainNVRAMDefPtr
+virDomainNVRAMDefParseXML(const xmlNodePtr node,
+                          unsigned int flags)
+{
+   virDomainNVRAMDefPtr def;
+
+    if (VIR_ALLOC(def) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
+        goto error;
+
+    return def;
+
+error:
+    virDomainNVRAMDefFree(def);
+    return NULL;
+}
+
 static virSysinfoDefPtr
 virSysinfoParseXML(const xmlNodePtr node,
                   xmlXPathContextPtr ctxt)
@@ -11306,6 +11347,23 @@ virDomainDefParseXML(xmlDocPtr xml,
     }
     VIR_FREE(nodes);
 
+    if ((n = virXPathNodeSet("./devices/nvram", ctxt, &nodes)) < 0) {
+        goto error;
+    }
+
+    if (n > 1) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("only a single nvram device is supported"));
+        goto error;
+    } else if (n == 1) {
+        virDomainNVRAMDefPtr nvram =
+            virDomainNVRAMDefParseXML(nodes[0], flags);
+        if (!nvram)
+            goto error;
+        def->nvram = nvram;
+        VIR_FREE(nodes);
+    }
+
     /* analysis of the hub devices */
     if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) {
         goto error;
@@ -14395,6 +14453,21 @@ virDomainMemballoonDefFormat(virBufferPtr buf,
     return 0;
 }
 
+static int
+virDomainNVRAMDefFormat(virBufferPtr buf,
+                        virDomainNVRAMDefPtr def,
+                        unsigned int flags)
+{
+    virBufferAddLit(buf, "    <nvram>\n");
+    if (virDomainDeviceInfoIsSet(&def->info, flags) &&
+        virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+        return -1;
+
+    virBufferAddLit(buf, "    </nvram>\n");
+
+    return 0;
+}
+
 static int
 virDomainSysinfoDefFormat(virBufferPtr buf,
                           virSysinfoDefPtr def)
@@ -15725,6 +15798,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
     if (def->rng)
         virDomainRNGDefFormat(buf, def->rng, flags);
 
+    if (def->nvram)
+        virDomainNVRAMDefFormat(buf, def->nvram, flags);
+
     virBufferAddLit(buf, "  </devices>\n");
 
     virBufferAdjustIndent(buf, 2);
@@ -17007,6 +17083,7 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_CHR:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
+    case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Copying definition of '%d' type "
index acf18f8b6c35afb8d6f5cc143e4e644abe79239b..d9ea1c1fba529b1877700d3a719cf54870e0b985 100644 (file)
@@ -109,6 +109,9 @@ typedef virDomainChrDef *virDomainChrDefPtr;
 typedef struct _virDomainMemballoonDef virDomainMemballoonDef;
 typedef virDomainMemballoonDef *virDomainMemballoonDefPtr;
 
+typedef struct _virDomainNVRAMDef virDomainNVRAMDef;
+typedef virDomainNVRAMDef *virDomainNVRAMDefPtr;
+
 typedef struct _virDomainSnapshotObj virDomainSnapshotObj;
 typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;
 
@@ -137,6 +140,7 @@ typedef enum {
     VIR_DOMAIN_DEVICE_SMARTCARD,
     VIR_DOMAIN_DEVICE_CHR,
     VIR_DOMAIN_DEVICE_MEMBALLOON,
+    VIR_DOMAIN_DEVICE_NVRAM,
     VIR_DOMAIN_DEVICE_RNG,
 
     VIR_DOMAIN_DEVICE_LAST
@@ -163,6 +167,7 @@ struct _virDomainDeviceDef {
         virDomainSmartcardDefPtr smartcard;
         virDomainChrDefPtr chr;
         virDomainMemballoonDefPtr memballoon;
+        virDomainNVRAMDefPtr nvram;
         virDomainRNGDefPtr rng;
     } data;
 };
@@ -1469,6 +1474,9 @@ struct _virDomainMemballoonDef {
     virDomainDeviceInfo info;
 };
 
+struct _virDomainNVRAMDef {
+    virDomainDeviceInfo info;
+};
 
 enum virDomainSmbiosMode {
     VIR_DOMAIN_SMBIOS_NONE = 0,
@@ -1916,6 +1924,7 @@ struct _virDomainDef {
     /* Only 1 */
     virDomainWatchdogDefPtr watchdog;
     virDomainMemballoonDefPtr memballoon;
+    virDomainNVRAMDefPtr nvram;
     virDomainTPMDefPtr tpm;
     virCPUDefPtr cpu;
     virSysinfoDefPtr sysinfo;
@@ -2076,6 +2085,7 @@ int virDomainChrSourceDefCopy(virDomainChrSourceDefPtr src,
 void virDomainSoundCodecDefFree(virDomainSoundCodecDefPtr def);
 void virDomainSoundDefFree(virDomainSoundDefPtr def);
 void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def);
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def);
 void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
 void virDomainVideoDefFree(virDomainVideoDefPtr def);
 virDomainHostdevDefPtr virDomainHostdevDefAlloc(void);