File 5dca09c1-expose-sev-domcaps.patch of Package libvirt.16766
commit 5dca09c170e26d572cab9b7b80a4347d4dc1907e
Author: Brijesh Singh <brijesh.singh@amd.com>
Date: Fri Jun 8 09:40:52 2018 -0500
conf: Expose SEV feature in domain capabilities
Extend hypervisor capabilities to include sev feature. When available,
hypervisor supports launching an encrypted VM on AMD platform. The
sev feature tag provides additional details like Platform Diffie-Hellman
(PDH) key and certificate chain which can be used by the guest owner to
establish a cryptographic session with the SEV firmware to negotiate
keys used for attestation or to provide secret during launch.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
Index: libvirt-4.0.0/docs/formatdomaincaps.html.in
===================================================================
--- libvirt-4.0.0.orig/docs/formatdomaincaps.html.in
+++ libvirt-4.0.0/docs/formatdomaincaps.html.in
@@ -417,6 +417,10 @@
<value>3</value>
</enum>
</gic>
+ <sev>
+ <cbitpos>47</cbitpos>
+ <reduced-phys-bits>1</reduced-phys-bits>
+ </sev>
</features>
</domainCapabilities>
</pre>
@@ -441,5 +445,31 @@
<code>gic</code> element.</dd>
</dl>
+ <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>
Index: libvirt-4.0.0/docs/schemas/domaincaps.rng
===================================================================
--- libvirt-4.0.0.orig/docs/schemas/domaincaps.rng
+++ libvirt-4.0.0/docs/schemas/domaincaps.rng
@@ -173,6 +173,9 @@
<element name='features'>
<interleave>
<ref name='gic'/>
+ <optional>
+ <ref name='sev'/>
+ </optional>
</interleave>
</element>
</define>
@@ -184,6 +187,17 @@
</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'>
Index: libvirt-4.0.0/src/conf/domain_capabilities.c
===================================================================
--- libvirt-4.0.0.orig/src/conf/domain_capabilities.c
+++ libvirt-4.0.0/src/conf/domain_capabilities.c
@@ -95,6 +95,7 @@ virDomainCapsDispose(void *obj)
VIR_FREE(caps->machine);
virObjectUnref(caps->cpu.custom);
virCPUDefFree(caps->cpu.hostModel);
+ virSEVCapabilitiesFree(caps->sev);
virDomainCapsStringValuesFree(&caps->os.loader.values);
}
@@ -561,6 +562,22 @@ virDomainCapsFeatureGICFormat(virBufferP
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)
@@ -599,6 +616,7 @@ virDomainCapsFormat(virDomainCapsPtr con
virBufferAdjustIndent(&buf, 2);
virDomainCapsFeatureGICFormat(&buf, &caps->gic);
+ virDomainCapsFeatureSEVFormat(&buf, caps->sev);
virBufferAdjustIndent(&buf, -2);
virBufferAddLit(&buf, "</features>\n");
Index: libvirt-4.0.0/src/conf/domain_capabilities.h
===================================================================
--- libvirt-4.0.0.orig/src/conf/domain_capabilities.h
+++ libvirt-4.0.0/src/conf/domain_capabilities.h
@@ -166,6 +166,7 @@ struct _virDomainCaps {
/* add new domain devices here */
virDomainCapsFeatureGIC gic;
+ virSEVCapabilityPtr sev;
/* add new domain features here */
};
Index: libvirt-4.0.0/src/qemu/qemu_capabilities.c
===================================================================
--- libvirt-4.0.0.orig/src/qemu/qemu_capabilities.c
+++ libvirt-4.0.0/src/qemu/qemu_capabilities.c
@@ -5893,6 +5893,48 @@ virQEMUCapsFillDomainFeatureGICCaps(virQ
}
+/**
+ * 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,
@@ -5924,8 +5966,10 @@ virQEMUCapsFillDomainCaps(virCapsPtr cap
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;
}