[libvirt] [PATCH v8 05/11] qemu: Add support to get the SEV info

Brijesh Singh posted 9 patches 7 years, 8 months ago
There is a newer version of this series
[libvirt] [PATCH v8 05/11] qemu: Add support to get the SEV info
Posted by Brijesh Singh 7 years, 8 months ago
Signed-off-by: Brijesh Singh <<brijesh.singh@amd.com>>
---
 src/qemu/qemu_capabilities.c |  7 ++++
 src/qemu/qemu_capabilities.h |  4 ++
 src/qemu/qemu_driver.c       | 91 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a2103e3..2b82da2 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2081,6 +2081,13 @@ virQEMUCapsSetSEVCapabilities(virQEMUCapsPtr qemuCaps,
 }
 
 
+virSEVCapabilityPtr
+virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps)
+{
+    return qemuCaps->sevCapabilities;
+}
+
+
 static int
 virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps,
                             qemuMonitorPtr mon)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 7390271..463d7d4 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -616,4 +616,8 @@ bool virQEMUCapsGuestIsNative(virArch host,
 
 bool virQEMUCapsCPUFilterFeatures(const char *name,
                                   void *opaque);
+
+virSEVCapabilityPtr
+virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps);
+
 #endif /* __QEMU_CAPABILITIES_H__*/
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 38ea865..c289b21 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -21437,6 +21437,96 @@ qemuDomainSetLifecycleAction(virDomainPtr dom,
 }
 
 
+static int
+qemuGetSEVInfo(virQEMUCapsPtr qemuCaps,
+               virTypedParameterPtr *params,
+               int *nparams,
+               unsigned int flags)
+{
+    int maxpar = 0;
+    virSEVCapabilityPtr sev = virQEMUCapsGetSEVCapabilities(qemuCaps);
+
+    virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
+
+    if (virTypedParamsAddString(params, nparams, &maxpar,
+                    VIR_NODE_SEV_PDH, sev->pdh) < 0)
+        return -1;
+
+    if (virTypedParamsAddString(params, nparams, &maxpar,
+                    VIR_NODE_SEV_CERT_CHAIN, sev->pdh) < 0)
+        goto cleanup;
+
+    if (virTypedParamsAddUInt(params, nparams, &maxpar,
+                    VIR_NODE_SEV_CBITPOS, sev->cbitpos) < 0)
+        goto cleanup;
+
+    if (virTypedParamsAddUInt(params, nparams, &maxpar,
+                    VIR_NODE_SEV_REDUCED_PHYS_BITS,
+                    sev->reduced_phys_bits) < 0)
+        goto cleanup;
+
+    return 0;
+
+ cleanup:
+    return -1;
+}
+
+
+static int
+qemuNodeGetSEVInfo(virConnectPtr conn,
+                   virTypedParameterPtr *params,
+                   int *nparams,
+                   unsigned int flags)
+{
+    virQEMUDriverPtr driver = conn->privateData;
+    virCapsPtr caps = NULL;
+    virQEMUCapsPtr qemucaps = NULL;
+    virArch hostarch;
+    virCapsDomainDataPtr capsdata;
+    int ret = -1;
+
+    if (virNodeGetSevInfoEnsureACL(conn) < 0)
+        return ret;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, true)))
+        return ret;
+
+    hostarch = virArchFromHost();
+    if (!(capsdata = virCapabilitiesDomainDataLookup(caps,
+            VIR_DOMAIN_OSTYPE_HVM, hostarch, VIR_DOMAIN_VIRT_QEMU,
+            NULL, NULL))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Cannot find suitable emulator for %s"),
+                       virArchToString(hostarch));
+        goto UnrefCaps;
+    }
+
+    qemucaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
+                                      capsdata->emulator);
+    VIR_FREE(capsdata);
+    if (!qemucaps)
+        goto UnrefCaps;
+
+    if (!virQEMUCapsGet(qemucaps, QEMU_CAPS_SEV_GUEST)) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("QEMU does not support SEV guest"));
+        goto UnrefQemuCaps;
+    }
+
+    if (qemuGetSEVInfo(qemucaps, params, nparams, flags) < 0)
+        goto UnrefQemuCaps;
+
+    ret = 0;
+
+ UnrefQemuCaps:
+    virObjectUnref(qemucaps);
+ UnrefCaps:
+    virObjectUnref(caps);
+
+    return ret;
+}
+
+
 static virHypervisorDriver qemuHypervisorDriver = {
     .name = QEMU_DRIVER_NAME,
     .connectURIProbe = qemuConnectURIProbe,
@@ -21660,6 +21750,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainSetLifecycleAction = qemuDomainSetLifecycleAction, /* 3.9.0 */
     .connectCompareHypervisorCPU = qemuConnectCompareHypervisorCPU, /* 4.4.0 */
     .connectBaselineHypervisorCPU = qemuConnectBaselineHypervisorCPU, /* 4.4.0 */
+    .nodeGetSEVInfo = qemuNodeGetSEVInfo, /* 4.5.0 */
 };
 
 
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v8 05/11] qemu: Add support to get the SEV info
Posted by Erik Skultety 7 years, 8 months ago
more verbose commit subject:
qemu: Implement the driver backend for virNodeGetSEVInfo

On Wed, Jun 06, 2018 at 12:50:11PM -0500, Brijesh Singh wrote:
> Signed-off-by: Brijesh Singh <<brijesh.singh@amd.com>>
> ---
>  src/qemu/qemu_capabilities.c |  7 ++++
>  src/qemu/qemu_capabilities.h |  4 ++
>  src/qemu/qemu_driver.c       | 91 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 102 insertions(+)
>

...

>
> +static int
> +qemuGetSEVInfo(virQEMUCapsPtr qemuCaps,

qemuGetSEVInfoToParams would IMHO be a better (iow less confusing) name.

> +               virTypedParameterPtr *params,
> +               int *nparams,
> +               unsigned int flags)
> +{
> +    int maxpar = 0;
> +    virSEVCapabilityPtr sev = virQEMUCapsGetSEVCapabilities(qemuCaps);
> +
> +    virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
> +
> +    if (virTypedParamsAddString(params, nparams, &maxpar,
> +                    VIR_NODE_SEV_PDH, sev->pdh) < 0)
> +        return -1;
> +
> +    if (virTypedParamsAddString(params, nparams, &maxpar,
> +                    VIR_NODE_SEV_CERT_CHAIN, sev->pdh) < 0)
> +        goto cleanup;
> +
> +    if (virTypedParamsAddUInt(params, nparams, &maxpar,
> +                    VIR_NODE_SEV_CBITPOS, sev->cbitpos) < 0)
> +        goto cleanup;
> +
> +    if (virTypedParamsAddUInt(params, nparams, &maxpar,
> +                    VIR_NODE_SEV_REDUCED_PHYS_BITS,
> +                    sev->reduced_phys_bits) < 0)
> +        goto cleanup;
> +
> +    return 0;
> +
> + cleanup:
> +    return -1;

So ^this cleanup label is pretty much unnecessary. In order to avoid weird
errors, we usually create a local copy of the caller-provided argument - in this
case params - work on it the whole time and only once it's safe, we do a
VIR_STEAL_PTR to the original pointer, so we should do that here as well.

> +}
> +
> +
> +static int
> +qemuNodeGetSEVInfo(virConnectPtr conn,
> +                   virTypedParameterPtr *params,
> +                   int *nparams,
> +                   unsigned int flags)
> +{
> +    virQEMUDriverPtr driver = conn->privateData;
> +    virCapsPtr caps = NULL;
> +    virQEMUCapsPtr qemucaps = NULL;
> +    virArch hostarch;
> +    virCapsDomainDataPtr capsdata;
> +    int ret = -1;
> +
> +    if (virNodeGetSevInfoEnsureACL(conn) < 0)
> +        return ret;
> +
> +    if (!(caps = virQEMUDriverGetCapabilities(driver, true)))
> +        return ret;
> +
> +    hostarch = virArchFromHost();
> +    if (!(capsdata = virCapabilitiesDomainDataLookup(caps,
> +            VIR_DOMAIN_OSTYPE_HVM, hostarch, VIR_DOMAIN_VIRT_QEMU,
> +            NULL, NULL))) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Cannot find suitable emulator for %s"),
> +                       virArchToString(hostarch));
> +        goto UnrefCaps;
> +    }

If you use virQEMUCapsCacheLookupByArch below instead, we could drop ^this hunk
above, am I right?

> +
> +    qemucaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
> +                                      capsdata->emulator);
> +    VIR_FREE(capsdata);

^this could be dropped...

> +    if (!qemucaps)
> +        goto UnrefCaps;
> +
> +    if (!virQEMUCapsGet(qemucaps, QEMU_CAPS_SEV_GUEST)) {
> +        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
> +                       _("QEMU does not support SEV guest"));
> +        goto UnrefQemuCaps;
> +    }
> +
> +    if (qemuGetSEVInfo(qemucaps, params, nparams, flags) < 0)
> +        goto UnrefQemuCaps;
> +
> +    ret = 0;
> +
> + UnrefQemuCaps:

s/UnrefQemuCaps/cleanup

> +    virObjectUnref(qemucaps);
> + UnrefCaps:
> +    virObjectUnref(caps);

..^this one too...

Erik

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v8 05/11] qemu: Add support to get the SEV info
Posted by Brijesh Singh 7 years, 8 months ago

On 06/07/2018 11:37 AM, Erik Skultety wrote:
> more verbose commit subject:
> qemu: Implement the driver backend for virNodeGetSEVInfo
> 
> On Wed, Jun 06, 2018 at 12:50:11PM -0500, Brijesh Singh wrote:
>> Signed-off-by: Brijesh Singh <<brijesh.singh@amd.com>>
>> ---
>>   src/qemu/qemu_capabilities.c |  7 ++++
>>   src/qemu/qemu_capabilities.h |  4 ++
>>   src/qemu/qemu_driver.c       | 91 ++++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 102 insertions(+)
>>
> 
> ...
> 
>>
>> +static int
>> +qemuGetSEVInfo(virQEMUCapsPtr qemuCaps,
> 
> qemuGetSEVInfoToParams would IMHO be a better (iow less confusing) name.


Agreed, its much better name.


> 
>> +               virTypedParameterPtr *params,
>> +               int *nparams,
>> +               unsigned int flags)
>> +{
>> +    int maxpar = 0;
>> +    virSEVCapabilityPtr sev = virQEMUCapsGetSEVCapabilities(qemuCaps);
>> +
>> +    virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
>> +
>> +    if (virTypedParamsAddString(params, nparams, &maxpar,
>> +                    VIR_NODE_SEV_PDH, sev->pdh) < 0)
>> +        return -1;
>> +
>> +    if (virTypedParamsAddString(params, nparams, &maxpar,
>> +                    VIR_NODE_SEV_CERT_CHAIN, sev->pdh) < 0)
>> +        goto cleanup;
>> +
>> +    if (virTypedParamsAddUInt(params, nparams, &maxpar,
>> +                    VIR_NODE_SEV_CBITPOS, sev->cbitpos) < 0)
>> +        goto cleanup;
>> +
>> +    if (virTypedParamsAddUInt(params, nparams, &maxpar,
>> +                    VIR_NODE_SEV_REDUCED_PHYS_BITS,
>> +                    sev->reduced_phys_bits) < 0)
>> +        goto cleanup;
>> +
>> +    return 0;
>> +
>> + cleanup:
>> +    return -1;
> 
> So ^this cleanup label is pretty much unnecessary. In order to avoid weird
> errors, we usually create a local copy of the caller-provided argument - in this
> case params - work on it the whole time and only once it's safe, we do a
> VIR_STEAL_PTR to the original pointer, so we should do that here as well.
> 


OK, will do so.


>> +}
>> +
>> +
>> +static int
>> +qemuNodeGetSEVInfo(virConnectPtr conn,
>> +                   virTypedParameterPtr *params,
>> +                   int *nparams,
>> +                   unsigned int flags)
>> +{
>> +    virQEMUDriverPtr driver = conn->privateData;
>> +    virCapsPtr caps = NULL;
>> +    virQEMUCapsPtr qemucaps = NULL;
>> +    virArch hostarch;
>> +    virCapsDomainDataPtr capsdata;
>> +    int ret = -1;
>> +
>> +    if (virNodeGetSevInfoEnsureACL(conn) < 0)
>> +        return ret;
>> +
>> +    if (!(caps = virQEMUDriverGetCapabilities(driver, true)))
>> +        return ret;
>> +
>> +    hostarch = virArchFromHost();
>> +    if (!(capsdata = virCapabilitiesDomainDataLookup(caps,
>> +            VIR_DOMAIN_OSTYPE_HVM, hostarch, VIR_DOMAIN_VIRT_QEMU,
>> +            NULL, NULL))) {
>> +        virReportError(VIR_ERR_INTERNAL_ERROR,
>> +                       _("Cannot find suitable emulator for %s"),
>> +                       virArchToString(hostarch));
>> +        goto UnrefCaps;
>> +    }
> 
> If you use virQEMUCapsCacheLookupByArch below instead, we could drop ^this hunk
> above, am I right?
> 


Ah, I was looking through code to find out suitable APIs for this. 
thanks for suggestion, it seems like it will work for us in this case.



>> +
>> +    qemucaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
>> +                                      capsdata->emulator);
>> +    VIR_FREE(capsdata);
> 
> ^this could be dropped...
> 

If we use virQEMUCapsCacheLookupByArch() then we could drop this.


>> +    if (!qemucaps)
>> +        goto UnrefCaps;
>> +
>> +    if (!virQEMUCapsGet(qemucaps, QEMU_CAPS_SEV_GUEST)) {
>> +        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
>> +                       _("QEMU does not support SEV guest"));
>> +        goto UnrefQemuCaps;
>> +    }
>> +
>> +    if (qemuGetSEVInfo(qemucaps, params, nparams, flags) < 0)
>> +        goto UnrefQemuCaps;
>> +
>> +    ret = 0;
>> +
>> + UnrefQemuCaps:
> 
> s/UnrefQemuCaps/cleanup
> 
>> +    virObjectUnref(qemucaps);
>> + UnrefCaps:
>> +    virObjectUnref(caps);
> 
> ..^this one too...
> 
> Erik
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list