</gic>
<vmcoreinfo supported='yes'/>
<genid supported='yes'/>
+ <sev>
+ <cbitpos>47</cbitpos>
+ <reduced-phys-bits>1</reduced-phys-bits>
+ </sev>
</features>
</domainCapabilities>
</pre>
<p>Reports whether the genid feature can be used by the domain.</p>
+ <h4><a id="elementsSEV">SEV capabilities</a></h4>
+
+ <p>AMD Secure Encrypted Virtualization (SEV) capabilities are exposed under
+ the <code>sev</code> element.
+ SEV is an extension to the AMD-V architecture which supports running
+ virtual machines (VMs) under the control of a hypervisor. When supported,
+ guest owner can create a VM whose memory contents will be transparently
+ encrypted with a key unique to that VM.</p>
+
+ <p>
+ For more details on SEV feature see:
+ <a href="https://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf">
+ SEV API spec</a> and <a href="http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf">
+ SEV White Paper</a>
+ </p>
+
+ <dl>
+ <dt><code>cbitpos</code></dt>
+ <dd>When memory encryption is enabled, one of the physical address bits
+ (aka the C-bit) is utilized to mark if a memory page is protected. The
+ C-bit position is Hypervisor dependent.</dd>
+ <dt><code>reduced-phys-bits</code></dt>
+ <dd>When memory encryption is enabled, we lose certain bits in physical
+ address space. The number of bits we lose is hypervisor dependent.</dd>
+ </dl>
+
</body>
</html>
<ref name='gic'/>
<ref name='vmcoreinfo'/>
<ref name='vmgenid'/>
+ <optional>
+ <ref name='sev'/>
+ </optional>
</interleave>
</element>
</define>
</element>
</define>
+ <define name='sev'>
+ <element name='sev'>
+ <element name='cbitpos'>
+ <data type='unsignedInt'/>
+ </element>
+ <element name='reduced-phys-bits'>
+ <data type='unsignedInt'/>
+ </element>
+ </element>
+ </define>
+
<define name='value'>
<zeroOrMore>
<element name='value'>
VIR_FREE(caps->machine);
virObjectUnref(caps->cpu.custom);
virCPUDefFree(caps->cpu.hostModel);
+ virSEVCapabilitiesFree(caps->sev);
virDomainCapsStringValuesFree(&caps->os.loader.values);
}
FORMAT_EPILOGUE(gic);
}
+static void
+virDomainCapsFeatureSEVFormat(virBufferPtr buf,
+ virSEVCapabilityPtr const sev)
+{
+ if (!sev)
+ return;
+
+ virBufferAddLit(buf, "<sev supported='yes'>\n");
+ virBufferAdjustIndent(buf, 2);
+ virBufferAsprintf(buf, "<cbitpos>%d</cbitpos>\n", sev->cbitpos);
+ virBufferAsprintf(buf, "<reduced-phys-bits>%d</reduced-phys-bits>\n",
+ sev->reduced_phys_bits);
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</sev>\n");
+}
+
char *
virDomainCapsFormat(virDomainCapsPtr const caps)
virBufferAsprintf(&buf, "<genid supported='%s'/>\n",
caps->genid ? "yes" : "no");
+ virDomainCapsFeatureSEVFormat(&buf, caps->sev);
virBufferAdjustIndent(&buf, -2);
virBufferAddLit(&buf, "</features>\n");
virDomainCapsFeatureGIC gic;
bool vmcoreinfo;
bool genid;
+ virSEVCapabilityPtr sev;
/* add new domain features here */
};
}
+/**
+ * virQEMUCapsFillDomainFeatureSEVCaps:
+ * @qemuCaps: QEMU capabilities
+ * @domCaps: domain capabilities
+ *
+ * Take the information about SEV capabilities that has been obtained
+ * using the 'query-sev-capabilities' QMP command and stored in @qemuCaps
+ * and convert it to a form suitable for @domCaps.
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int
+virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCapsPtr qemuCaps,
+ virDomainCapsPtr domCaps)
+{
+ virSEVCapability *sev;
+ virSEVCapability *cap = qemuCaps->sevCapabilities;
+ int ret = -1;
+
+ if (!cap)
+ return 0;
+
+ if (VIR_ALLOC(sev) < 0)
+ return -1;
+
+ if (VIR_STRDUP(sev->pdh, cap->pdh) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(sev->cert_chain, cap->cert_chain) < 0)
+ goto cleanup;
+
+ sev->cbitpos = cap->cbitpos;
+ sev->reduced_phys_bits = cap->reduced_phys_bits;
+ VIR_STEAL_PTR(domCaps->sev, sev);
+
+ ret = 0;
+ cleanup:
+ virSEVCapabilitiesFree(sev);
+ return ret;
+}
+
+
int
virQEMUCapsFillDomainCaps(virCapsPtr caps,
virDomainCapsPtr domCaps,
virQEMUCapsFillDomainDeviceGraphicsCaps(qemuCaps, graphics) < 0 ||
virQEMUCapsFillDomainDeviceVideoCaps(qemuCaps, video) < 0 ||
virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev) < 0 ||
- virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps) < 0)
+ virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps) < 0 ||
+ virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps) < 0)
return -1;
+
return 0;
}