diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f3e3de4c1c..6d6cfb6dc4 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4506,6 +4506,40 @@ qemu-kvm -net nic,model=? /dev/null
+
+
+ nvram device is always added to pSeries guest on PPC64, and its address
+ is allowed to be changed. Element nvram (only valid for
+ pSeries guest, since 1.0.5) is provided to
+ enable the address setting.
+
+
+ Example: usage of NVRAM configuration
+
+
+ ...
+ <devices>
+ <nvram>
+ <address type='spapr-vio' reg='0x3000'/>
+ </nvram>
+ </devices>
+ ...
+
+
+ spapr-vio
+ -
+
+ VIO device address type, only valid for PPC64.
+
+
+ reg
+ -
+
+ Device address
+
+
+
+
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a9d05817d9..0c1b76aea0 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2797,6 +2797,13 @@
+
+
+
+
+
+
+
@@ -3284,6 +3291,9 @@
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0b432dd3d8..958b77beee 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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, " \n");
+ if (virDomainDeviceInfoIsSet(&def->info, flags) &&
+ virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+
+ virBufferAddLit(buf, " \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, " \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 "
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index acf18f8b6c..d9ea1c1fba 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -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);