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