[libvirt][PATCH v13 4/6] conf: expose SGX feature in domain capabilities

Huang, Haibin haibin.huang at intel.com
Mon Jul 25 02:36:42 UTC 2022


Ok, nice comments

Thank you very much!

> -----Original Message-----
> From: Michal Prívozník <mprivozn at redhat.com>
> Sent: Wednesday, July 20, 2022 7:27 PM
> To: Yang, Lin A <lin.a.yang at intel.com>; libvir-list at redhat.com; Huang, Haibin
> <haibin.huang at intel.com>; Ding, Jian-feng <jian-feng.ding at intel.com>
> Subject: Re: [libvirt][PATCH v13 4/6] conf: expose SGX feature in domain
> capabilities
> 
> On 7/1/22 21:14, Lin Yang wrote:
> > From: Haibin Huang <haibin.huang at intel.com>
> >
> > Extend hypervisor capabilities to include sgx feature. When available,
> > the hypervisor supports launching an VM with SGX on Intel platfrom.
> > The SGX feature tag privides additional details like section size and
> > sgx1 or sgx2.
> >
> > Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> > Signed-off-by: Haibin Huang <haibin.huang at intel.com>
> > ---
> >  docs/formatdomaincaps.rst                     | 40 ++++++++++++++++
> >  src/conf/domain_capabilities.c                | 48 +++++++++++++++++++
> >  src/conf/schemas/domaincaps.rng               | 42 ++++++++++++++++
> >  src/qemu/qemu_capabilities.c                  | 28 +++++++++++
> >  tests/domaincapsdata/bhyve_basic.x86_64.xml   |  1 +
> >  tests/domaincapsdata/bhyve_fbuf.x86_64.xml    |  1 +
> >  tests/domaincapsdata/bhyve_uefi.x86_64.xml    |  1 +
> >  tests/domaincapsdata/empty.xml                |  1 +
> >  tests/domaincapsdata/libxl-xenfv.xml          |  1 +
> >  tests/domaincapsdata/libxl-xenpv.xml          |  1 +
> >  .../domaincapsdata/qemu_2.11.0-q35.x86_64.xml |  1 +
> > .../domaincapsdata/qemu_2.11.0-tcg.x86_64.xml |  1 +
> >  tests/domaincapsdata/qemu_2.11.0.s390x.xml    |  1 +
> >  tests/domaincapsdata/qemu_2.11.0.x86_64.xml   |  1 +
> >  .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml |  1 +
> > .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml |  1 +
> >  .../qemu_2.12.0-virt.aarch64.xml              |  1 +
> >  tests/domaincapsdata/qemu_2.12.0.aarch64.xml  |  1 +
> >  tests/domaincapsdata/qemu_2.12.0.ppc64.xml    |  1 +
> >  tests/domaincapsdata/qemu_2.12.0.s390x.xml    |  1 +
> >  tests/domaincapsdata/qemu_2.12.0.x86_64.xml   |  1 +
> >  .../domaincapsdata/qemu_3.0.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_3.0.0-tcg.x86_64.xml  |  1 +
> >  tests/domaincapsdata/qemu_3.0.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_3.0.0.s390x.xml     |  1 +
> >  tests/domaincapsdata/qemu_3.0.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_3.1.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_3.1.0-tcg.x86_64.xml  |  1 +
> >  tests/domaincapsdata/qemu_3.1.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_3.1.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_4.0.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_4.0.0-tcg.x86_64.xml  |  1 +
> >  .../qemu_4.0.0-virt.aarch64.xml               |  1 +
> >  tests/domaincapsdata/qemu_4.0.0.aarch64.xml   |  1 +
> >  tests/domaincapsdata/qemu_4.0.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_4.0.0.s390x.xml     |  1 +
> >  tests/domaincapsdata/qemu_4.0.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_4.1.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml  |  1 +
> >  tests/domaincapsdata/qemu_4.1.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml  |  1 +
> >  .../qemu_4.2.0-virt.aarch64.xml               |  1 +
> >  tests/domaincapsdata/qemu_4.2.0.aarch64.xml   |  1 +
> >  tests/domaincapsdata/qemu_4.2.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_4.2.0.s390x.xml     |  1 +
> >  tests/domaincapsdata/qemu_4.2.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |  1 +
> >  .../qemu_5.0.0-virt.aarch64.xml               |  1 +
> >  tests/domaincapsdata/qemu_5.0.0.aarch64.xml   |  1 +
> >  tests/domaincapsdata/qemu_5.0.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_5.0.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |  1 +
> >  tests/domaincapsdata/qemu_5.1.0.sparc.xml     |  1 +
> >  tests/domaincapsdata/qemu_5.1.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |  1 +
> >  .../qemu_5.2.0-virt.aarch64.xml               |  1 +
> >  tests/domaincapsdata/qemu_5.2.0.aarch64.xml   |  1 +
> >  tests/domaincapsdata/qemu_5.2.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_5.2.0.s390x.xml     |  1 +
> >  tests/domaincapsdata/qemu_5.2.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |  1 +
> >  .../qemu_6.0.0-virt.aarch64.xml               |  1 +
> >  tests/domaincapsdata/qemu_6.0.0.aarch64.xml   |  1 +
> >  tests/domaincapsdata/qemu_6.0.0.s390x.xml     |  1 +
> >  tests/domaincapsdata/qemu_6.0.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |  1 +
> > .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |  1 +
> >  tests/domaincapsdata/qemu_6.1.0.x86_64.xml    |  1 +
> >  .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |  6 +++
> > .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |  6 +++
> >  .../qemu_6.2.0-virt.aarch64.xml               |  1 +
> >  tests/domaincapsdata/qemu_6.2.0.aarch64.xml   |  1 +
> >  tests/domaincapsdata/qemu_6.2.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_6.2.0.x86_64.xml    |  6 +++
> >  .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  | 10 ++++
> > .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  | 10 ++++
> >  .../qemu_7.0.0-virt.aarch64.xml               |  1 +
> >  tests/domaincapsdata/qemu_7.0.0.aarch64.xml   |  1 +
> >  tests/domaincapsdata/qemu_7.0.0.ppc64.xml     |  1 +
> >  tests/domaincapsdata/qemu_7.0.0.x86_64.xml    | 10 ++++
> >  .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  | 10 ++++
> > .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  | 10 ++++
> >  tests/domaincapsdata/qemu_7.1.0.x86_64.xml    | 10 ++++
> >  88 files changed, 311 insertions(+)
> >
> > diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
> > index 933469b2a2..d3bdee28d4 100644
> > --- a/docs/formatdomaincaps.rst
> > +++ b/docs/formatdomaincaps.rst
> > @@ -519,6 +519,16 @@ capabilities. All features occur as children of the
> main ``features`` element.
> >           <cbitpos>47</cbitpos>
> >           <reduced-phys-bits>1</reduced-phys-bits>
> >         </sev>
> > +       <sgx supported='yes'>
> > +         <flc>no</flc>
> > +         <sgx1>yes</sgx1>
> > +         <sgx2>no</sgx2>
> > +         <section_size>2</section_size>
> > +         <sections>
> > +           <section node='0' size='1'/>
> > +           <section node='1' size='1'/>
> > +         </sections>
> > +       </sgx>
> >       </features>
> >     </domainCapabilities>
> >
> > @@ -598,3 +608,33 @@ in domain XML
> > <formatdomain.html#launch-security>`__
> >  ``maxESGuests``
> >     The maximum number of SEV-ES guests that can be launched on the host.
> This
> >     value may be configurable in the firmware for some hosts.
> > +
> > +SGX capabilities
> > +^^^^^^^^^^^^^^^^
> > +
> > +Intel Software Guard Extensions (Intel SGX) capabilities are exposed
> > +under the ``sgx`` element.
> > +
> > +Intel SGX helps protect data in use via unique application isolation
> technology.
> > +Protect selected code and data from modification using hardened
> > +enclaves with Intel SGX.
> > +
> > +For more details on the SGX feature, please follow resources in the
> > +SGX developer's document store. In order to use SGX with libvirt have
> > +a look at formatdomain.rst Memory devices.
> > +
> > +``flc``
> > +   FLC (Flexible Launch Control), not strictly part of SGX2, but was not part
> of
> > +   original SGX hardware either.
> > +
> > +``sgx1``
> > +   the sgx version 1.
> > +
> > +``sgx2``
> > +   The sgx version 2.
> > +
> > +``section_size``
> > +   The size of the SGX enclave page cache (called EPC).
> > +
> > +``sections``
> > +   The sections of the SGX enclave page cache (called EPC).
> > diff --git a/src/conf/domain_capabilities.c
> > b/src/conf/domain_capabilities.c index 27f3fb8d36..fa29f69807 100644
> > --- a/src/conf/domain_capabilities.c
> > +++ b/src/conf/domain_capabilities.c
> > @@ -98,6 +98,7 @@ virDomainCapsDispose(void *obj)
> >      virObjectUnref(caps->cpu.custom);
> >      virCPUDefFree(caps->cpu.hostModel);
> >      virSEVCapabilitiesFree(caps->sev);
> > +    virSGXCapabilitiesFree(caps->sgx);
> >
> >      values = &caps->os.loader.values;
> >      for (i = 0; i < values->nvalues; i++) @@ -620,6 +621,52 @@
> > virDomainCapsFeatureSEVFormat(virBuffer *buf,
> >      return;
> >  }
> >
> > +static void
> > +virDomainCapsFeatureSGXFormat(virBuffer *buf,
> > +                              const virSGXCapability *sgx) {
> > +    size_t i;
> > +
> > +    if (!sgx) {
> > +        virBufferAddLit(buf, "<sgx supported='no'/>\n");
> > +    } else {
> > +        virBufferAddLit(buf, "<sgx supported='yes'>\n");
> > +        virBufferAdjustIndent(buf, 2);
> > +        if (sgx->flc) {
> > +            virBufferAsprintf(buf, "<flc>%s</flc>\n", "yes");
> > +        } else {
> > +            virBufferAsprintf(buf, "<flc>%s</flc>\n", "no");
> > +        }
> 
> Same comment here as in the previous patch.
> 
> > +        if (sgx->sgx1) {
> > +            virBufferAsprintf(buf, "<sgx1>%s</sgx1>\n", "yes");
> > +        } else {
> > +            virBufferAsprintf(buf, "<sgx1>%s</sgx1>\n", "no");
> > +        }
> > +        if (sgx->sgx2) {
> > +            virBufferAsprintf(buf, "<sgx2>%s</sgx2>\n", "yes");
> > +        } else {
> > +            virBufferAsprintf(buf, "<sgx2>%s</sgx2>\n", "no");
> > +        }
> > +        virBufferAsprintf(buf, "<section_size
> > + unit='KiB'>%llu</section_size>\n", sgx->section_size);
> > +
> > +        if (sgx->nSections > 0) {
> > +            virBufferAddLit(buf, "<sections>\n");
> > +
> > +            for (i = 0; i < sgx->nSections; i++) {
> > +                virBufferAdjustIndent(buf, 2);
> > +                virBufferAsprintf(buf, "<section node='%u' ", sgx-
> >pSections[i].node);
> > +                virBufferAsprintf(buf, "size='%llu'/>\n", sgx->pSections[i].size);
> > +                virBufferAdjustIndent(buf, -2);
> > +            }
> > +            virBufferAddLit(buf, "</sections>\n");
> > +        }
> > +
> > +        virBufferAdjustIndent(buf, -2);
> > +        virBufferAddLit(buf, "</sgx>\n");
> > +    }
> > +
> > +    return;
> > +}
> >
> >  static void
> >  virDomainCapsFormatFeatures(const virDomainCaps *caps, @@ -640,6
> > +687,7 @@ virDomainCapsFormatFeatures(const virDomainCaps *caps,
> >      }
> >
> >      virDomainCapsFeatureSEVFormat(&childBuf, caps->sev);
> > +    virDomainCapsFeatureSGXFormat(&childBuf, caps->sgx);
> >
> >      virXMLFormatElement(buf, "features", NULL, &childBuf);  } diff
> > --git a/src/conf/schemas/domaincaps.rng
> > b/src/conf/schemas/domaincaps.rng index 9cbc2467ab..6975ebacb9
> 100644
> > --- a/src/conf/schemas/domaincaps.rng
> > +++ b/src/conf/schemas/domaincaps.rng
> > @@ -270,6 +270,9 @@
> >        <optional>
> >          <ref name="sev"/>
> >        </optional>
> > +      <optional>
> > +        <ref name="sgx"/>
> > +      </optional>
> >      </element>
> >    </define>
> >
> > @@ -330,6 +333,45 @@
> >      </element>
> >    </define>
> >
> > +  <define name="sgx">
> > +    <element name="sgx">
> > +      <ref name="supported"/>
> > +      <optional>
> > +        <element name="flc">
> > +          <data type="string"/>
> 
> Or, since we know we are formatting yes/no, we can use virYesNo instead of
> too generic string type.
> 
> > +        </element>
> > +        <element name="sgx1">
> > +          <data type="string"/>
> > +        </element>
> > +        <element name="sgx2">
> > +          <data type="string"/>
> > +        </element>
> > +        <element name="section_size">
> > +          <attribute name="unit">
> > +            <value>KiB</value>
> > +          </attribute>
> > +          <data type="unsignedInt"/>
> > +        </element>
> > +        <optional>
> > +          <element name="sections">
> > +            <interleave>
> 
> I think the order is well defined and thus we don't really need <interleave/>
> here. The domain capabilities XML is not provided by user, it's generated by
> libvirt, in virDomainCapsFormat() where the order is well defined.
> 
> > +              <zeroOrMore>
> > +                <element name="section">
> > +                  <attribute name="node">
> > +                    <data type="string"/>
> 
> This is an integer ..
> 
> > +                  </attribute>
> > +                  <attribute name="size">
> > +                    <data type="string"/>
> 
> .. and so is this.
> 
> > +                  </attribute>
> > +                </element>
> > +              </zeroOrMore>
> > +            </interleave>
> > +          </element>
> > +        </optional>
> > +      </optional>
> > +    </element>
> > +  </define>
> > +
> >    <define name="value">
> >      <zeroOrMore>
> >        <element name="value">
> > diff --git a/src/qemu/qemu_capabilities.c
> > b/src/qemu/qemu_capabilities.c index 57b5acb150..598c694738 100644
> > --- a/src/qemu/qemu_capabilities.c
> > +++ b/src/qemu/qemu_capabilities.c
> > @@ -6744,6 +6744,33 @@
> virQEMUCapsFillDomainFeatureS390PVCaps(virQEMUCaps *qemuCaps,
> >      }
> >  }
> >
> > +/**
> > + * virQEMUCapsFillDomainFeatureiSGXCaps:
> > + * @qemuCaps: QEMU capabilities
> > + * @domCaps: domain capabilities
> > + *
> > + * Take the information about SGX capabilities that has been obtained
> > + * using the 'query-sgx-capabilities' QMP command and stored in
> > + at qemuCaps
> > + * and convert it to a form suitable for @domCaps.
> > + */
> > +static void
> > +virQEMUCapsFillDomainFeatureSGXCaps(virQEMUCaps *qemuCaps,
> > +                                    virDomainCaps *domCaps) {
> > +    virSGXCapability *cap = qemuCaps->sgxCapabilities;
> > +
> > +    if (!cap)
> > +        return;
> > +
> > +    domCaps->sgx = g_new0(virSGXCapability, 1);
> > +
> > +    domCaps->sgx->flc = cap->flc;
> > +    domCaps->sgx->sgx1 = cap->sgx1;
> > +    domCaps->sgx->sgx2 = cap->sgx2;
> > +    domCaps->sgx->section_size = cap->section_size;
> > +    domCaps->sgx->nSections = cap->nSections;
> > +    domCaps->sgx->pSections = cap->pSections;
> 
> This is a verbatim copy of virQEMUCapsSGXInfoCopy(), any reason for not
> just call the function?
> 
> > +}
> 
> Michal



More information about the libvir-list mailing list