diff mbox series

[RESEND,29/32] qmp: Add the qmp_query_sgx_capabilities()

Message ID 20210430062455.8117-30-yang.zhong@intel.com
State New
Headers show
Series Qemu SGX virtualization | expand

Commit Message

Yang Zhong April 30, 2021, 6:24 a.m. UTC
The libvirt can use qmp_query_sgx_capabilities() to get the host
sgx capabilitis.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
---
 hw/i386/sgx-epc.c          | 66 ++++++++++++++++++++++++++++++++++++++
 include/hw/i386/pc.h       |  1 +
 monitor/qmp-cmds.c         |  5 +++
 qapi/misc.json             | 19 +++++++++++
 stubs/sgx-stub.c           |  5 +++
 tests/qtest/qmp-cmd-test.c |  1 +
 6 files changed, 97 insertions(+)

Comments

Eric Blake May 3, 2021, 6 p.m. UTC | #1
On 4/30/21 1:24 AM, Yang Zhong wrote:
> The libvirt can use qmp_query_sgx_capabilities() to get the host

s/The libvirt/Libvirt/

> sgx capabilitis.
> 

capabilities

> Signed-off-by: Yang Zhong <yang.zhong@intel.com>
> ---
>  hw/i386/sgx-epc.c          | 66 ++++++++++++++++++++++++++++++++++++++
>  include/hw/i386/pc.h       |  1 +
>  monitor/qmp-cmds.c         |  5 +++
>  qapi/misc.json             | 19 +++++++++++
>  stubs/sgx-stub.c           |  5 +++
>  tests/qtest/qmp-cmd-test.c |  1 +
>  6 files changed, 97 insertions(+)
> 

> +++ b/qapi/misc.json
> @@ -561,3 +561,22 @@
>  #
>  ##
>  { 'command': 'query-sgx', 'returns': 'SGXInfo' }
> +
> +
> +##
> +# @query-sgx-capabilities:
> +#
> +# Returns information from host SGX capabilities
> +#
> +# Returns: @SGXInfo
> +#
> +# Since: 5.1

6.1

> +#
> +# Example:
> +#
> +# -> { "execute": "query-sgx-capabilities" }
> +# <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true,
> +#                  "flc": true, "section-size" : 0 } }
> +#
> +##
> +{ 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo' }
> diff --git a/stubs/sgx-stub.c b/stubs/sgx-stub.c
> index c2b59a88fd..1dedf3f3db 100644
> --- a/stubs/sgx-stub.c
Yang Zhong May 6, 2021, 8:57 a.m. UTC | #2
On Mon, May 03, 2021 at 01:00:37PM -0500, Eric Blake wrote:
> On 4/30/21 1:24 AM, Yang Zhong wrote:
> > The libvirt can use qmp_query_sgx_capabilities() to get the host
> 
> s/The libvirt/Libvirt/
> 
> > sgx capabilitis.
> > 
> 
> capabilities
> 
  Eric, thanks for your comments! I will change those mistakes, thanks!

  Yang
  
> > Signed-off-by: Yang Zhong <yang.zhong@intel.com>
> > ---
> >  hw/i386/sgx-epc.c          | 66 ++++++++++++++++++++++++++++++++++++++
> >  include/hw/i386/pc.h       |  1 +
> >  monitor/qmp-cmds.c         |  5 +++
> >  qapi/misc.json             | 19 +++++++++++
> >  stubs/sgx-stub.c           |  5 +++
> >  tests/qtest/qmp-cmd-test.c |  1 +
> >  6 files changed, 97 insertions(+)
> > 
> 
> > +++ b/qapi/misc.json
> > @@ -561,3 +561,22 @@
> >  #
> >  ##
> >  { 'command': 'query-sgx', 'returns': 'SGXInfo' }
> > +
> > +
> > +##
> > +# @query-sgx-capabilities:
> > +#
> > +# Returns information from host SGX capabilities
> > +#
> > +# Returns: @SGXInfo
> > +#
> > +# Since: 5.1
> 
> 6.1
> 

  Ditto, thanks!

  Yang


> > +#
> > +# Example:
> > +#
> > +# -> { "execute": "query-sgx-capabilities" }
> > +# <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true,
> > +#                  "flc": true, "section-size" : 0 } }
> > +#
> > +##
> > +{ 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo' }
> > diff --git a/stubs/sgx-stub.c b/stubs/sgx-stub.c
> > index c2b59a88fd..1dedf3f3db 100644
> > --- a/stubs/sgx-stub.c
> -- 
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3226
> Virtualization:  qemu.org | libvirt.org
diff mbox series

Patch

diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c
index 7daea0613b..0995956f99 100644
--- a/hw/i386/sgx-epc.c
+++ b/hw/i386/sgx-epc.c
@@ -27,6 +27,14 @@ 
 
 uint32_t epc_num;
 
+#define SGX_MAX_EPC_SECTIONS            8
+#define SGX_CPUID_EPC_INVALID           0x0
+
+/* A valid EPC section. */
+#define SGX_CPUID_EPC_SECTION           0x1
+
+#define SGX_CPUID_EPC_MASK              GENMASK(3, 0)
+
 static Property sgx_epc_properties[] = {
     DEFINE_PROP_UINT64(SGX_EPC_ADDR_PROP, SGXEPCDevice, addr, 0),
     DEFINE_PROP_LINK(SGX_EPC_MEMDEV_PROP, SGXEPCDevice, hostmem,
@@ -344,6 +352,64 @@  SGXInfo *sgx_get_info(void)
     return info;
 }
 
+static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high)
+{
+    return (low & GENMASK_ULL(31, 12)) +
+           ((high & GENMASK_ULL(19, 0)) << 32);
+}
+
+static uint64_t sgx_calc_host_epc_section_size(void)
+{
+    uint32_t i, type;
+    uint32_t eax, ebx, ecx, edx;
+    uint64_t size = 0;
+
+    for (i = 0; i < SGX_MAX_EPC_SECTIONS; i++) {
+        host_cpuid(0x12, i + 2, &eax, &ebx, &ecx, &edx);
+
+        type = eax & SGX_CPUID_EPC_MASK;
+        if (type == SGX_CPUID_EPC_INVALID) {
+            break;
+        }
+
+        if (type != SGX_CPUID_EPC_SECTION) {
+            break;
+        }
+
+        size += sgx_calc_section_metric(ecx, edx);
+    }
+
+    return size;
+}
+
+SGXInfo *sgx_get_capabilities(Error **errp)
+{
+    SGXInfo *info = NULL;
+    uint32_t eax, ebx, ecx, edx;
+
+    int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR);
+    if (fd < 0) {
+        error_setg(errp, "SGX is not enabled in KVM");
+        return NULL;
+    }
+
+    info = g_new0(SGXInfo, 1);
+    host_cpuid(0x7, 0, &eax, &ebx, &ecx, &edx);
+
+    info->sgx = ebx & (1U << 2) ? true : false;
+    info->flc = ecx & (1U << 30) ? true : false;
+
+    host_cpuid(0x12, 0, &eax, &ebx, &ecx, &edx);
+    info->sgx1 = eax & (1U << 0) ? true : false;
+    info->sgx2 = eax & (1U << 1) ? true : false;
+
+    info->section_size = sgx_calc_host_epc_section_size();
+
+    close(fd);
+
+    return info;
+}
+
 static QemuOptsList sgx_epc_opts = {
     .name = "sgx-epc",
     .implied_opt_name = "id",
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index cb74298117..a66795da0f 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -205,6 +205,7 @@  void pc_machine_init_sgx_epc(PCMachineState *pcms);
 void sgx_memory_backend_reset(HostMemoryBackend *backend, int fd,
                               Error **errp);
 SGXInfo *sgx_get_info(void);
+SGXInfo *sgx_get_capabilities(Error **errp);
 
 extern GlobalProperty pc_compat_5_2[];
 extern const size_t pc_compat_5_2_len;
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 48f7708ffe..f1360e9f4e 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -365,3 +365,8 @@  SGXInfo *qmp_query_sgx(Error **errp)
 
     return info;
 }
+
+SGXInfo *qmp_query_sgx_capabilities(Error **errp)
+{
+    return sgx_get_capabilities(errp);
+}
diff --git a/qapi/misc.json b/qapi/misc.json
index 112a2f71cf..3f50b42d37 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -561,3 +561,22 @@ 
 #
 ##
 { 'command': 'query-sgx', 'returns': 'SGXInfo' }
+
+
+##
+# @query-sgx-capabilities:
+#
+# Returns information from host SGX capabilities
+#
+# Returns: @SGXInfo
+#
+# Since: 5.1
+#
+# Example:
+#
+# -> { "execute": "query-sgx-capabilities" }
+# <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true,
+#                  "flc": true, "section-size" : 0 } }
+#
+##
+{ 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo' }
diff --git a/stubs/sgx-stub.c b/stubs/sgx-stub.c
index c2b59a88fd..1dedf3f3db 100644
--- a/stubs/sgx-stub.c
+++ b/stubs/sgx-stub.c
@@ -5,3 +5,8 @@  SGXInfo *sgx_get_info(void)
 {
     return NULL;
 }
+
+SGXInfo *sgx_get_capabilities(Error **errp)
+{
+    return NULL;
+}
diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
index b75f3364f3..1af2f74c28 100644
--- a/tests/qtest/qmp-cmd-test.c
+++ b/tests/qtest/qmp-cmd-test.c
@@ -101,6 +101,7 @@  static bool query_is_ignored(const char *cmd)
         "query-sev",
         "query-sev-capabilities",
         "query-sgx",
+        "query-sgx-capabilities",
         NULL
     };
     int i;