mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
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>
This commit is contained in:
parent
d4005609f3
commit
5dca09c170
@ -435,6 +435,10 @@
|
||||
</gic>
|
||||
<vmcoreinfo supported='yes'/>
|
||||
<genid supported='yes'/>
|
||||
<sev>
|
||||
<cbitpos>47</cbitpos>
|
||||
<reduced-phys-bits>1</reduced-phys-bits>
|
||||
</sev>
|
||||
</features>
|
||||
</domainCapabilities>
|
||||
</pre>
|
||||
@ -467,5 +471,31 @@
|
||||
|
||||
<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>
|
||||
|
@ -185,6 +185,9 @@
|
||||
<ref name='gic'/>
|
||||
<ref name='vmcoreinfo'/>
|
||||
<ref name='vmgenid'/>
|
||||
<optional>
|
||||
<ref name='sev'/>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
@ -208,6 +211,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'>
|
||||
|
@ -88,6 +88,7 @@ virDomainCapsDispose(void *obj)
|
||||
VIR_FREE(caps->machine);
|
||||
virObjectUnref(caps->cpu.custom);
|
||||
virCPUDefFree(caps->cpu.hostModel);
|
||||
virSEVCapabilitiesFree(caps->sev);
|
||||
|
||||
virDomainCapsStringValuesFree(&caps->os.loader.values);
|
||||
}
|
||||
@ -554,6 +555,22 @@ virDomainCapsFeatureGICFormat(virBufferPtr buf,
|
||||
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)
|
||||
@ -600,6 +617,7 @@ 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");
|
||||
|
@ -169,6 +169,7 @@ struct _virDomainCaps {
|
||||
virDomainCapsFeatureGIC gic;
|
||||
bool vmcoreinfo;
|
||||
bool genid;
|
||||
virSEVCapabilityPtr sev;
|
||||
/* add new domain features here */
|
||||
};
|
||||
|
||||
|
@ -5157,6 +5157,48 @@ virQEMUCapsFillDomainFeatureGICCaps(virQEMUCapsPtr qemuCaps,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@ -5194,8 +5236,10 @@ virQEMUCapsFillDomainCaps(virCapsPtr caps,
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user