On 2/27/2018 10:29 AM, Brijesh Singh
wrote:
On 02/27/2018 02:15 AM, Peter Krempa wrote:
On Mon, Feb 26, 2018 at 11:53:34 -0600,
Brijesh Singh wrote:
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
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@xxxxxxx>
---
docs/formatdomaincaps.html.in | 31
+++++++++++++++++++++++++++++++
docs/schemas/domaincaps.rng | 10 ++++++++++
src/conf/domain_capabilities.c | 19 +++++++++++++++++++
src/conf/domain_capabilities.h | 11 +++++++++++
src/qemu/qemu_capabilities.c | 41
++++++++++++++++++++++++++++++++++++++++-
5 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomaincaps.html.in
b/docs/formatdomaincaps.html.in
index 6bfcaf61caae..8f833477772c 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -417,6 +417,12 @@
<value>3</value>
</enum>
</gic>
+ <sev supported='yes'>
+ <pdh> </pdh>
+ <cert-chain> </cert-chain>
+ <cbitpos> </cbitpos>
+ <reduced-phys-bits>
</reduced-phys-bits>
+ </sev>
</features>
</domainCapabilities>
</pre>
@@ -441,5 +447,30 @@
<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.
So is it likely that anything similar will be introduced by
other
manufacturers too? I'd like to avoid having these to be
per-manufacturer
specific. Can we change this to be more generic?
How about something like:
<memory-encryption type='sev'>
<pdh> ..</pdh>
....
....
</memory-encryption>
if other manufacture implements memory encryption then we can
introduce a new type to handle new memory encryption feature. The
inputs to the memory encryption type is going to be
vendor-specific.
+ </p>
+
+ <dl>
+ <dt><code>pdh</code></dt>
+ <dd>Platform diffie-hellman key, which can be
exported to remote entities
+ which wish to establish a secure transport context with
the SEV platform
+ in order to transmit data securely. The key is encoded
in base64</dd>
+
<dt><code>cert-chain</code></dt>
+ <dd> Platform certificate chain -- which includes
platform endorsement key
+ (PEK), owners certificate authory (OCA) and chip
endorsement key (CEK).
+ The certificate chain is encoded in base64.</dd>
+ <dt><code>cbitpos</code></dt>
+ <dd> C-bit position in page-table
entry</dd>
+
<dt><code>reduced-phys-bits</code></dt>
+ <dd> Physical Address bit reduction</dd>
So these really are not clear from this description.
I will add some more details to clarify this.
+ </dl>
+
</body>
</html>
diff --git a/docs/schemas/domaincaps.rng
b/docs/schemas/domaincaps.rng
index 39053181eb9a..6ce8d296c703 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -184,6 +184,16 @@
</element>
</define>
+ <define name='sev'>
+ <element name='sev'>
+ <ref name='supported'/>
+ <ref name='pdh'/>
+ <ref name='cert-chain'/>
+ <ref name='cbitpos'/>
+ <ref name='reduced-phys-bits'/>
You are not really defining these names anywhere. This will most
probably break the schema test.
I must admit that I am new to libvirt hence need some help. Sorry
I am not able to follow your this comment. Do I need to update
domaincap.rng or not ? If yes, where do I need to define the names
so that we don't break the schema test. Any tips is appreciated.
thanks
I think Peter is talking virt-xml-validate or similar scheme test.
In one of our internal review I have put the def for sev tags at
/docs/schemas/domaincommon.rng. If it is what he talked about we will add def for new sev
tags and verify correspondent XML files with virt-xml-validate.
+ </element>
+ </define>
+
<define name='value'>
<zeroOrMore>
<element name='value'>
diff --git a/src/conf/domain_capabilities.c
b/src/conf/domain_capabilities.c
index f7d9be50f82d..6a7a30877042 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -549,6 +549,24 @@
virDomainCapsFeatureGICFormat(virBufferPtr buf,
FORMAT_EPILOGUE(gic);
}
+static void
+virDomainCapsFeatureSEVFormat(virBufferPtr buf,
+ virDomainCapsFeatureSEVPtr
const sev)
+{
+ FORMAT_PROLOGUE(sev);
If the feature is not supported, you should not format an empty
element
here. Just skip it completely.
OK, actually I was taking similar approach as 'gic' support --
which leaves the empty element in case if gic is not present. Will
now take your recommendation and skip it completely.
+
+ if (sev->supported) {
+ virBufferAsprintf(buf,
"<cbitpos>%d</cbitpos>\n", sev->cbitpos);
+ virBufferAsprintf(buf,
"<reduced-phys-bits>%d</reduced-phys-bits>\n",
+ sev->reduced_phys_bits);
+ virBufferAsprintf(buf, "<pdh>%s</pdh>\n",
sev->pdh);
+ virBufferAsprintf(buf,
"<cert-chain>%s</cert-chain>\n",
+ sev->cert_chain);
+ }
+
+ FORMAT_EPILOGUE(sev);
+}
+
char *
virDomainCapsFormat(virDomainCapsPtr const caps)
@@ -587,6 +605,7 @@ virDomainCapsFormat(virDomainCapsPtr const
caps)
virBufferAdjustIndent(&buf, 2);
virDomainCapsFeatureGICFormat(&buf,
&caps->gic);
+ virDomainCapsFeatureSEVFormat(&buf,
&caps->sev);
virBufferAdjustIndent(&buf, -2);
virBufferAddLit(&buf, "</features>\n");
diff --git a/src/conf/domain_capabilities.h
b/src/conf/domain_capabilities.h
index e13a7fd6ba1b..aed5ec28e9cc 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -102,6 +102,16 @@ struct _virDomainCapsFeatureGIC {
virDomainCapsEnum version; /* Info about virGICVersion
*/
};
+typedef struct _virDomainCapsFeatureSEV
virDomainCapsFeatureSEV;
+typedef virDomainCapsFeatureSEV *virDomainCapsFeatureSEVPtr;
+struct _virDomainCapsFeatureSEV {
+ bool supported;
+ char *pdh; /* host platform-diffie hellman key */
+ char *cert_chain; /* PDH certificate chain */
+ int cbitpos;
+ int reduced_phys_bits;
This structure is basically the same as the one in the qemu
driver.
Can't you just use this one in the qemu driver?
Yes they are same structure, will reuse it.
+};
+
typedef enum {
VIR_DOMCAPS_CPU_USABLE_UNKNOWN,
VIR_DOMCAPS_CPU_USABLE_YES,
@@ -171,6 +181,7 @@ struct _virDomainCaps {
/* add new domain devices here */
virDomainCapsFeatureGIC gic;
+ virDomainCapsFeatureSEV sev;
/* add new domain features here */
};
diff --git a/src/qemu/qemu_capabilities.c
b/src/qemu/qemu_capabilities.c
index 2c680528deb8..ee8c542679eb 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -5880,6 +5880,44 @@
virQEMUCapsSupportsGICVersion(virQEMUCapsPtr qemuCaps,
return false;
}
+/**
+ * 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.
This function would not be necessary in that case.
+ *
+ * Returns: 0 on success, <0 on failure
+ */
+static int
+virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCapsPtr qemuCaps,
+ virDomainCapsPtr domCaps)
+{
+ virDomainCapsFeatureSEVPtr sev = &domCaps->sev;
+ virSEVCapability *cap = qemuCaps->sevCapabilities;
+
+ if (!cap)
+ return 0;
+
+ sev->supported = cap->sev;
+
+ if (VIR_STRDUP(sev->pdh, cap->pdh) < 0)
+ goto failed;
+
+ if (VIR_STRDUP(sev->cert_chain, cap->cert_chain)
< 0)
+ goto failed;
+
+ sev->cbitpos = cap->cbitpos;
+ sev->reduced_phys_bits = cap->reduced_phys_bits;
+
+ return 0;
+failed:
+ sev->supported = false;
+ return 0;
So why does this function return anything? Also we prefer the
'error'
label in this case.
The function was modeled after gic feature which always returns 0
regardless whether gic is available or not. Similarly we don't
want to fail just because SEV feature is not available. I can look
into improving this.
|