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@amd.com>
---
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.
+ </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>
+ </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'/>
+ </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 (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;
+};
+
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.
+ *
+ * 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;
+}
+
/**
* virQEMUCapsFillDomainFeatureGICCaps:
@@ -5958,7 +5996,8 @@ 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))
return -1;
return 0;
}
--
2.14.3
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
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@amd.com>
> ---
> 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?
> + </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.
> + </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.
> + </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.
> +
> + 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?
> +};
> +
> 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.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
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@amd.com>
>> ---
>> 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
>> + </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.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
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@amd.com>
>>> ---
>>> 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.
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.