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