60061b
From ea46a86ba6319ea98573c65af5186cd5399ab0ce Mon Sep 17 00:00:00 2001
60061b
From: Yang Zhong <yang.zhong@intel.com>
60061b
Date: Mon, 1 Nov 2021 12:20:07 -0400
60061b
Subject: [PATCH 2/7] numa: Support SGX numa in the monitor and Libvirt
60061b
 interfaces
60061b
60061b
RH-Author: Paul Lai <None>
60061b
RH-MergeRequest: 111: numa: Enable numa for SGX EPC sections
60061b
RH-Commit: [2/5] 403c4f98dccd023293cd3246081ae12f4782bed0
60061b
RH-Bugzilla: 1518984
60061b
RH-Acked-by: Paolo Bonzini <None>
60061b
RH-Acked-by: Bandan Das <None>
60061b
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
60061b
60061b
Add the SGXEPCSection list into SGXInfo to show the multiple
60061b
SGX EPC sections detailed info, not the total size like before.
60061b
This patch can enable numa support for 'info sgx' command and
60061b
QMP interfaces. The new interfaces show each EPC section info
60061b
in one numa node. Libvirt can use QMP interface to get the
60061b
detailed host SGX EPC capabilities to decide how to allocate
60061b
host EPC sections to guest.
60061b
60061b
(qemu) info sgx
60061b
 SGX support: enabled
60061b
 SGX1 support: enabled
60061b
 SGX2 support: enabled
60061b
 FLC support: enabled
60061b
 NUMA node #0: size=67108864
60061b
 NUMA node #1: size=29360128
60061b
60061b
The QMP interface show:
60061b
(QEMU) query-sgx
60061b
{"return": {"sgx": true, "sgx2": true, "sgx1": true, "sections": \
60061b
[{"node": 0, "size": 67108864}, {"node": 1, "size": 29360128}], "flc": true}}
60061b
60061b
(QEMU) query-sgx-capabilities
60061b
{"return": {"sgx": true, "sgx2": true, "sgx1": true, "sections": \
60061b
[{"node": 0, "size": 17070817280}, {"node": 1, "size": 17079205888}], "flc": true}}
60061b
60061b
Signed-off-by: Yang Zhong <yang.zhong@intel.com>
60061b
Message-Id: <20211101162009.62161-4-yang.zhong@intel.com>
60061b
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
60061b
(cherry picked from commit 4755927ae12547c2e7cb22c5fa1b39038c6c11b1)
60061b
Signed-off-by: Paul Lai <plai@redhat.com>
60061b
---
60061b
 hw/i386/sgx.c         | 51 +++++++++++++++++++++++++++++++++++--------
60061b
 qapi/misc-target.json | 19 ++++++++++++++--
60061b
 2 files changed, 59 insertions(+), 11 deletions(-)
60061b
60061b
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
60061b
index d04299904a..5de5dd0893 100644
60061b
--- a/hw/i386/sgx.c
60061b
+++ b/hw/i386/sgx.c
60061b
@@ -83,11 +83,13 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high)
60061b
            ((high & MAKE_64BIT_MASK(0, 20)) << 32);
60061b
 }
60061b
 
60061b
-static uint64_t sgx_calc_host_epc_section_size(void)
60061b
+static SGXEPCSectionList *sgx_calc_host_epc_sections(void)
60061b
 {
60061b
+    SGXEPCSectionList *head = NULL, **tail = &head;
60061b
+    SGXEPCSection *section;
60061b
     uint32_t i, type;
60061b
     uint32_t eax, ebx, ecx, edx;
60061b
-    uint64_t size = 0;
60061b
+    uint32_t j = 0;
60061b
 
60061b
     for (i = 0; i < SGX_MAX_EPC_SECTIONS; i++) {
60061b
         host_cpuid(0x12, i + 2, &eax, &ebx, &ecx, &edx;;
60061b
@@ -101,10 +103,13 @@ static uint64_t sgx_calc_host_epc_section_size(void)
60061b
             break;
60061b
         }
60061b
 
60061b
-        size += sgx_calc_section_metric(ecx, edx);
60061b
+        section = g_new0(SGXEPCSection, 1);
60061b
+        section->node = j++;
60061b
+        section->size = sgx_calc_section_metric(ecx, edx);
60061b
+        QAPI_LIST_APPEND(tail, section);
60061b
     }
60061b
 
60061b
-    return size;
60061b
+    return head;
60061b
 }
60061b
 
60061b
 static void sgx_epc_reset(void *opaque)
60061b
@@ -168,13 +173,35 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp)
60061b
     info->sgx1 = eax & (1U << 0) ? true : false;
60061b
     info->sgx2 = eax & (1U << 1) ? true : false;
60061b
 
60061b
-    info->section_size = sgx_calc_host_epc_section_size();
60061b
+    info->sections = sgx_calc_host_epc_sections();
60061b
 
60061b
     close(fd);
60061b
 
60061b
     return info;
60061b
 }
60061b
 
60061b
+static SGXEPCSectionList *sgx_get_epc_sections_list(void)
60061b
+{
60061b
+    GSList *device_list = sgx_epc_get_device_list();
60061b
+    SGXEPCSectionList *head = NULL, **tail = &head;
60061b
+    SGXEPCSection *section;
60061b
+
60061b
+    for (; device_list; device_list = device_list->next) {
60061b
+        DeviceState *dev = device_list->data;
60061b
+        Object *obj = OBJECT(dev);
60061b
+
60061b
+        section = g_new0(SGXEPCSection, 1);
60061b
+        section->node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP,
60061b
+                                                 &error_abort);
60061b
+        section->size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP,
60061b
+                                                 &error_abort);
60061b
+        QAPI_LIST_APPEND(tail, section);
60061b
+    }
60061b
+    g_slist_free(device_list);
60061b
+
60061b
+    return head;
60061b
+}
60061b
+
60061b
 SGXInfo *qmp_query_sgx(Error **errp)
60061b
 {
60061b
     SGXInfo *info = NULL;
60061b
@@ -193,14 +220,13 @@ SGXInfo *qmp_query_sgx(Error **errp)
60061b
         return NULL;
60061b
     }
60061b
 
60061b
-    SGXEPCState *sgx_epc = &pcms->sgx_epc;
60061b
     info = g_new0(SGXInfo, 1);
60061b
 
60061b
     info->sgx = true;
60061b
     info->sgx1 = true;
60061b
     info->sgx2 = true;
60061b
     info->flc = true;
60061b
-    info->section_size = sgx_epc->size;
60061b
+    info->sections = sgx_get_epc_sections_list();
60061b
 
60061b
     return info;
60061b
 }
60061b
@@ -208,6 +234,7 @@ SGXInfo *qmp_query_sgx(Error **errp)
60061b
 void hmp_info_sgx(Monitor *mon, const QDict *qdict)
60061b
 {
60061b
     Error *err = NULL;
60061b
+    SGXEPCSectionList *section_list, *section;
60061b
     g_autoptr(SGXInfo) info = qmp_query_sgx(&err;;
60061b
 
60061b
     if (err) {
60061b
@@ -222,8 +249,14 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict)
60061b
                    info->sgx2 ? "enabled" : "disabled");
60061b
     monitor_printf(mon, "FLC support: %s\n",
60061b
                    info->flc ? "enabled" : "disabled");
60061b
-    monitor_printf(mon, "size: %" PRIu64 "\n",
60061b
-                   info->section_size);
60061b
+
60061b
+    section_list = info->sections;
60061b
+    for (section = section_list; section; section = section->next) {
60061b
+        monitor_printf(mon, "NUMA node #%" PRId64 ": ",
60061b
+                       section->value->node);
60061b
+        monitor_printf(mon, "size=%" PRIu64 "\n",
60061b
+                       section->value->size);
60061b
+    }
60061b
 }
60061b
 
60061b
 bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
60061b
diff --git a/qapi/misc-target.json b/qapi/misc-target.json
60061b
index 5aa2b95b7d..1022aa0184 100644
60061b
--- a/qapi/misc-target.json
60061b
+++ b/qapi/misc-target.json
60061b
@@ -337,6 +337,21 @@
60061b
   'if': 'TARGET_ARM' }
60061b
 
60061b
 
60061b
+##
60061b
+# @SGXEPCSection:
60061b
+#
60061b
+# Information about intel SGX EPC section info
60061b
+#
60061b
+# @node: the numa node
60061b
+#
60061b
+# @size: the size of epc section
60061b
+#
60061b
+# Since: 6.2
60061b
+##
60061b
+{ 'struct': 'SGXEPCSection',
60061b
+  'data': { 'node': 'int',
60061b
+            'size': 'uint64'}}
60061b
+
60061b
 ##
60061b
 # @SGXInfo:
60061b
 #
60061b
@@ -350,7 +365,7 @@
60061b
 #
60061b
 # @flc: true if FLC is supported
60061b
 #
60061b
-# @section-size: The EPC section size for guest
60061b
+# @sections: The EPC sections info for guest
60061b
 #
60061b
 # Since: 6.2
60061b
 ##
60061b
@@ -359,7 +374,7 @@
60061b
             'sgx1': 'bool',
60061b
             'sgx2': 'bool',
60061b
             'flc': 'bool',
60061b
-            'section-size': 'uint64'},
60061b
+            'sections': ['SGXEPCSection']},
60061b
    'if': 'TARGET_I386' }
60061b
 
60061b
 ##
60061b
-- 
60061b
2.27.0
60061b