diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in index e0814cb9a2..6be553a114 100644 --- a/docs/formatdomaincaps.html.in +++ b/docs/formatdomaincaps.html.in @@ -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> @@ -467,5 +471,31 @@

Reports whether the genid feature can be used by the domain.

+

SEV capabilities

+ +

AMD Secure Encrypted Virtualization (SEV) capabilities are exposed under + the sev 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.

+ +

+ For more details on SEV feature see: + + SEV API spec and + SEV White Paper +

+ +
+
cbitpos
+
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.
+
reduced-phys-bits
+
When memory encryption is enabled, we lose certain bits in physical + address space. The number of bits we lose is hypervisor dependent.
+
+ diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng index 5ceabb0a80..1d0a2e17aa 100644 --- a/docs/schemas/domaincaps.rng +++ b/docs/schemas/domaincaps.rng @@ -185,6 +185,9 @@ + + + @@ -208,6 +211,17 @@ + + + + + + + + + + + diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 3589777524..ec469bfb9a 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -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, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "%d\n", sev->cbitpos); + virBufferAsprintf(buf, "%d\n", + sev->reduced_phys_bits); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + char * virDomainCapsFormat(virDomainCapsPtr const caps) @@ -600,6 +617,7 @@ virDomainCapsFormat(virDomainCapsPtr const caps) virBufferAsprintf(&buf, "\n", caps->genid ? "yes" : "no"); + virDomainCapsFeatureSEVFormat(&buf, caps->sev); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "\n"); diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index 56c1903cf4..755de1365f 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -169,6 +169,7 @@ struct _virDomainCaps { virDomainCapsFeatureGIC gic; bool vmcoreinfo; bool genid; + virSEVCapabilityPtr sev; /* add new domain features here */ }; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 8b3ffe1afe..1803ed9875 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -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; }