495e37
From 6274a2a09a8931188889467b104bf2e2fc39cb54 Mon Sep 17 00:00:00 2001
495e37
From: Yang Zhong <yang.zhong@intel.com>
495e37
Date: Mon, 1 Nov 2021 12:20:05 -0400
495e37
Subject: [PATCH 01/12] numa: Enable numa for SGX EPC sections
495e37
495e37
RH-Author: Paul Lai <plai@redhat.com>
495e37
RH-MergeRequest: 65: Enable SGX and add SGX Numa support
495e37
RH-Commit: [1/5] ff69d138c3f5903096388ec7ccf8dc5e6c6c6ffb
495e37
RH-Bugzilla: 2033708
495e37
RH-Acked-by: Paolo Bonzini <None>
495e37
RH-Acked-by: Bandan Das <None>
495e37
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
495e37
495e37
The basic SGX did not enable numa for SGX EPC sections, which
495e37
result in all EPC sections located in numa node 0. This patch
495e37
enable SGX numa function in the guest and the EPC section can
495e37
work with RAM as one numa node.
495e37
495e37
The Guest kernel related log:
495e37
[    0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff]
495e37
[    0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff]
495e37
The SRAT table can normally show SGX EPC sections menory info in different
495e37
numa nodes.
495e37
495e37
The SGX EPC numa related command:
495e37
 ......
495e37
 -m 4G,maxmem=20G \
495e37
 -smp sockets=2,cores=2 \
495e37
 -cpu host,+sgx-provisionkey \
495e37
 -object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \
495e37
 -object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \
495e37
 -numa node,nodeid=0,cpus=0-1,memdev=node0 \
495e37
 -object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \
495e37
 -object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \
495e37
 -numa node,nodeid=1,cpus=2-3,memdev=node1 \
495e37
 -M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1 \
495e37
 ......
495e37
495e37
Signed-off-by: Yang Zhong <yang.zhong@intel.com>
495e37
Message-Id: <20211101162009.62161-2-yang.zhong@intel.com>
495e37
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
495e37
(cherry picked from commit 1105812382e1126d86dddc16b3700f8c79dc93d1)
495e37
Signed-off-by: Paul Lai <plai@redhat.com>
495e37
---
495e37
 hw/core/numa.c            |  5 ++---
495e37
 hw/i386/acpi-build.c      |  2 ++
495e37
 hw/i386/sgx-epc.c         |  3 +++
495e37
 hw/i386/sgx-stub.c        |  4 ++++
495e37
 hw/i386/sgx.c             | 44 +++++++++++++++++++++++++++++++++++++++
495e37
 include/hw/i386/sgx-epc.h |  3 +++
495e37
 monitor/hmp-cmds.c        |  1 +
495e37
 qapi/machine.json         | 10 ++++++++-
495e37
 qemu-options.hx           |  4 ++--
495e37
 9 files changed, 70 insertions(+), 6 deletions(-)
495e37
495e37
diff --git a/hw/core/numa.c b/hw/core/numa.c
495e37
index e6050b2273..1aa05dcf42 100644
495e37
--- a/hw/core/numa.c
495e37
+++ b/hw/core/numa.c
495e37
@@ -784,9 +784,8 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[])
495e37
                 break;
495e37
             case MEMORY_DEVICE_INFO_KIND_SGX_EPC:
495e37
                 se = value->u.sgx_epc.data;
495e37
-                /* TODO: once we support numa, assign to right node */
495e37
-                node_mem[0].node_mem += se->size;
495e37
-                node_mem[0].node_plugged_mem += se->size;
495e37
+                node_mem[se->node].node_mem += se->size;
495e37
+                node_mem[se->node].node_plugged_mem = 0;
495e37
                 break;
495e37
             default:
495e37
                 g_assert_not_reached();
495e37
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
495e37
index a99c6e4fe3..8383b83ee3 100644
495e37
--- a/hw/i386/acpi-build.c
495e37
+++ b/hw/i386/acpi-build.c
495e37
@@ -2068,6 +2068,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
495e37
         nvdimm_build_srat(table_data);
495e37
     }
495e37
 
495e37
+    sgx_epc_build_srat(table_data);
495e37
+
495e37
     /*
495e37
      * TODO: this part is not in ACPI spec and current linux kernel boots fine
495e37
      * without these entries. But I recall there were issues the last time I
495e37
diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c
495e37
index e508827e78..96b2940d75 100644
495e37
--- a/hw/i386/sgx-epc.c
495e37
+++ b/hw/i386/sgx-epc.c
495e37
@@ -21,6 +21,7 @@
495e37
 
495e37
 static Property sgx_epc_properties[] = {
495e37
     DEFINE_PROP_UINT64(SGX_EPC_ADDR_PROP, SGXEPCDevice, addr, 0),
495e37
+    DEFINE_PROP_UINT32(SGX_EPC_NUMA_NODE_PROP, SGXEPCDevice, node, 0),
495e37
     DEFINE_PROP_LINK(SGX_EPC_MEMDEV_PROP, SGXEPCDevice, hostmem,
495e37
                      TYPE_MEMORY_BACKEND_EPC, HostMemoryBackendEpc *),
495e37
     DEFINE_PROP_END_OF_LIST(),
495e37
@@ -139,6 +140,8 @@ static void sgx_epc_md_fill_device_info(const MemoryDeviceState *md,
495e37
     se->memaddr = epc->addr;
495e37
     se->size = object_property_get_uint(OBJECT(epc), SGX_EPC_SIZE_PROP,
495e37
                                         NULL);
495e37
+    se->node = object_property_get_uint(OBJECT(epc), SGX_EPC_NUMA_NODE_PROP,
495e37
+                                        NULL);
495e37
     se->memdev = object_get_canonical_path(OBJECT(epc->hostmem));
495e37
 
495e37
     info->u.sgx_epc.data = se;
495e37
diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c
495e37
index c9b379e665..26833eb233 100644
495e37
--- a/hw/i386/sgx-stub.c
495e37
+++ b/hw/i386/sgx-stub.c
495e37
@@ -6,6 +6,10 @@
495e37
 #include "qapi/error.h"
495e37
 #include "qapi/qapi-commands-misc-target.h"
495e37
 
495e37
+void sgx_epc_build_srat(GArray *table_data)
495e37
+{
495e37
+}
495e37
+
495e37
 SGXInfo *qmp_query_sgx(Error **errp)
495e37
 {
495e37
     error_setg(errp, "SGX support is not compiled in");
495e37
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
495e37
index 8fef3dd8fa..d04299904a 100644
495e37
--- a/hw/i386/sgx.c
495e37
+++ b/hw/i386/sgx.c
495e37
@@ -23,6 +23,7 @@
495e37
 #include "sysemu/hw_accel.h"
495e37
 #include "sysemu/reset.h"
495e37
 #include <sys/ioctl.h>
495e37
+#include "hw/acpi/aml-build.h"
495e37
 
495e37
 #define SGX_MAX_EPC_SECTIONS            8
495e37
 #define SGX_CPUID_EPC_INVALID           0x0
495e37
@@ -36,6 +37,46 @@
495e37
 
495e37
 #define RETRY_NUM                       2
495e37
 
495e37
+static int sgx_epc_device_list(Object *obj, void *opaque)
495e37
+{
495e37
+    GSList **list = opaque;
495e37
+
495e37
+    if (object_dynamic_cast(obj, TYPE_SGX_EPC)) {
495e37
+        *list = g_slist_append(*list, DEVICE(obj));
495e37
+    }
495e37
+
495e37
+    object_child_foreach(obj, sgx_epc_device_list, opaque);
495e37
+    return 0;
495e37
+}
495e37
+
495e37
+static GSList *sgx_epc_get_device_list(void)
495e37
+{
495e37
+    GSList *list = NULL;
495e37
+
495e37
+    object_child_foreach(qdev_get_machine(), sgx_epc_device_list, &list);
495e37
+    return list;
495e37
+}
495e37
+
495e37
+void sgx_epc_build_srat(GArray *table_data)
495e37
+{
495e37
+    GSList *device_list = sgx_epc_get_device_list();
495e37
+
495e37
+    for (; device_list; device_list = device_list->next) {
495e37
+        DeviceState *dev = device_list->data;
495e37
+        Object *obj = OBJECT(dev);
495e37
+        uint64_t addr, size;
495e37
+        int node;
495e37
+
495e37
+        node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP,
495e37
+                                        &error_abort);
495e37
+        addr = object_property_get_uint(obj, SGX_EPC_ADDR_PROP, &error_abort);
495e37
+        size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP, &error_abort);
495e37
+
495e37
+        build_srat_memory(table_data, addr, size, node, MEM_AFFINITY_ENABLED);
495e37
+    }
495e37
+    g_slist_free(device_list);
495e37
+}
495e37
+
495e37
 static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high)
495e37
 {
495e37
     return (low & MAKE_64BIT_MASK(12, 20)) +
495e37
@@ -226,6 +267,9 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms)
495e37
         /* set the memdev link with memory backend */
495e37
         object_property_parse(obj, SGX_EPC_MEMDEV_PROP, list->value->memdev,
495e37
                               &error_fatal);
495e37
+        /* set the numa node property for sgx epc object */
495e37
+        object_property_set_uint(obj, SGX_EPC_NUMA_NODE_PROP, list->value->node,
495e37
+                             &error_fatal);
495e37
         object_property_set_bool(obj, "realized", true, &error_fatal);
495e37
         object_unref(obj);
495e37
     }
495e37
diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h
495e37
index a6a65be854..581fac389a 100644
495e37
--- a/include/hw/i386/sgx-epc.h
495e37
+++ b/include/hw/i386/sgx-epc.h
495e37
@@ -25,6 +25,7 @@
495e37
 #define SGX_EPC_ADDR_PROP "addr"
495e37
 #define SGX_EPC_SIZE_PROP "size"
495e37
 #define SGX_EPC_MEMDEV_PROP "memdev"
495e37
+#define SGX_EPC_NUMA_NODE_PROP "node"
495e37
 
495e37
 /**
495e37
  * SGXEPCDevice:
495e37
@@ -38,6 +39,7 @@ typedef struct SGXEPCDevice {
495e37
 
495e37
     /* public */
495e37
     uint64_t addr;
495e37
+    uint32_t node;
495e37
     HostMemoryBackendEpc *hostmem;
495e37
 } SGXEPCDevice;
495e37
 
495e37
@@ -56,6 +58,7 @@ typedef struct SGXEPCState {
495e37
 } SGXEPCState;
495e37
 
495e37
 bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size);
495e37
+void sgx_epc_build_srat(GArray *table_data);
495e37
 
495e37
 static inline uint64_t sgx_epc_above_4g_end(SGXEPCState *sgx_epc)
495e37
 {
495e37
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
495e37
index 9c91bf93e9..2669156b28 100644
495e37
--- a/monitor/hmp-cmds.c
495e37
+++ b/monitor/hmp-cmds.c
495e37
@@ -1810,6 +1810,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
495e37
                                se->id ? se->id : "");
495e37
                 monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", se->memaddr);
495e37
                 monitor_printf(mon, "  size: %" PRIu64 "\n", se->size);
495e37
+                monitor_printf(mon, "  node: %" PRId64 "\n", se->node);
495e37
                 monitor_printf(mon, "  memdev: %s\n", se->memdev);
495e37
                 break;
495e37
             default:
495e37
diff --git a/qapi/machine.json b/qapi/machine.json
495e37
index 067e3f5378..16e771affc 100644
495e37
--- a/qapi/machine.json
495e37
+++ b/qapi/machine.json
495e37
@@ -1207,12 +1207,15 @@
495e37
 #
495e37
 # @memdev: memory backend linked with device
495e37
 #
495e37
+# @node: the numa node
495e37
+#
495e37
 # Since: 6.2
495e37
 ##
495e37
 { 'struct': 'SgxEPCDeviceInfo',
495e37
   'data': { '*id': 'str',
495e37
             'memaddr': 'size',
495e37
             'size': 'size',
495e37
+            'node': 'int',
495e37
             'memdev': 'str'
495e37
           }
495e37
 }
495e37
@@ -1285,10 +1288,15 @@
495e37
 #
495e37
 # @memdev: memory backend linked with device
495e37
 #
495e37
+# @node: the numa node
495e37
+#
495e37
 # Since: 6.2
495e37
 ##
495e37
 { 'struct': 'SgxEPC',
495e37
-  'data': { 'memdev': 'str' } }
495e37
+  'data': { 'memdev': 'str',
495e37
+            'node': 'int'
495e37
+          }
495e37
+}
495e37
 
495e37
 ##
495e37
 # @SgxEPCProperties:
495e37
diff --git a/qemu-options.hx b/qemu-options.hx
495e37
index 94c4a8dbaf..4b7798088b 100644
495e37
--- a/qemu-options.hx
495e37
+++ b/qemu-options.hx
495e37
@@ -127,11 +127,11 @@ SRST
495e37
 ERST
495e37
 
495e37
 DEF("M", HAS_ARG, QEMU_OPTION_M,
495e37
-    "                sgx-epc.0.memdev=memid\n",
495e37
+    "                sgx-epc.0.memdev=memid,sgx-epc.0.node=numaid\n",
495e37
     QEMU_ARCH_ALL)
495e37
 
495e37
 SRST
495e37
-``sgx-epc.0.memdev=@var{memid}``
495e37
+``sgx-epc.0.memdev=@var{memid},sgx-epc.0.node=@var{numaid}``
495e37
     Define an SGX EPC section.
495e37
 ERST
495e37
 
495e37
-- 
495e37
2.27.0
495e37