@@ -21,6 +21,7 @@
#include "qapi/qapi-visit-common.h"
#include "qapi/qapi-visit-machine.h"
#include "qapi/visitor.h"
+#include "qapi/clone-visitor.h"
#include "hw/sysbus.h"
#include "sysemu/cpus.h"
#include "sysemu/sysemu.h"
@@ -851,6 +852,35 @@ out_free:
qapi_free_SMPConfiguration(config);
}
+static void machine_get_sgx_epc(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+ SgxEPC *sgx = &(SgxEPC){
+ .id = ms->sgx_epc.id,
+ .memdev = ms->sgx_epc.memdev,
+ };
+
+ if (!visit_type_SgxEPC(v, name, &sgx, errp)) {
+ return;
+ }
+}
+
+static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+ SgxEPC *sgx;
+
+ if (!visit_type_SgxEPC(v, name, &sgx, errp)) {
+ return;
+ }
+
+ ms->sgx_epc.id = QAPI_CLONE(strList, sgx->id);
+ ms->sgx_epc.memdev = QAPI_CLONE(strList, sgx->memdev);
+ qapi_free_SgxEPC(sgx);
+}
+
static void machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -956,6 +986,12 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "memory-backend",
"Set RAM backend"
"Valid value is ID of hostmem based backend");
+
+ object_class_property_add(oc, "sgx-epc", "SgxEPC",
+ machine_get_sgx_epc, machine_set_sgx_epc,
+ NULL, NULL);
+ object_class_property_set_description(oc, "sgx-epc",
+ "SGX EPC device");
}
static void machine_class_base_init(ObjectClass *oc, void *data)
@@ -6,6 +6,7 @@ i386_ss.add(files(
'multiboot.c',
'x86.c',
'sgx-epc.c',
+ 'sgx.c'
))
i386_ss.add(when: 'CONFIG_X86_IOMMU', if_true: files('x86-iommu.c'),
@@ -14,13 +14,8 @@
#include "hw/i386/sgx-epc.h"
#include "hw/mem/memory-device.h"
#include "hw/qdev-properties.h"
-#include "monitor/qdev.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
-#include "qemu/config-file.h"
-#include "qemu/error-report.h"
-#include "qemu/option.h"
-#include "qemu/units.h"
#include "target/i386/cpu.h"
#include "exec/address-spaces.h"
@@ -56,6 +51,8 @@ static void sgx_epc_realize(DeviceState *dev, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
X86MachineState *x86ms = X86_MACHINE(pcms);
+ MemoryDeviceState *md = MEMORY_DEVICE(dev);
+ SGXEPCState *sgx_epc = pcms->sgx_epc;
SGXEPCDevice *epc = SGX_EPC(dev);
const char *path;
@@ -74,7 +71,18 @@ static void sgx_epc_realize(DeviceState *dev, Error **errp)
return;
}
- error_setg(errp, "'" TYPE_SGX_EPC "' not supported");
+ epc->addr = sgx_epc->base + sgx_epc->size;
+
+ memory_region_add_subregion(&sgx_epc->mr, epc->addr - sgx_epc->base,
+ host_memory_backend_get_memory(epc->hostmem));
+
+ host_memory_backend_set_mapped(epc->hostmem, true);
+
+ sgx_epc->sections = g_renew(SGXEPCDevice *, sgx_epc->sections,
+ sgx_epc->nr_sections + 1);
+ sgx_epc->sections[sgx_epc->nr_sections++] = epc;
+
+ sgx_epc->size += memory_device_get_region_size(md, errp);
}
static void sgx_epc_unrealize(DeviceState *dev)
new file mode 100644
@@ -0,0 +1,72 @@
+/*
+ * SGX common code
+ *
+ * Copyright (C) 2021 Intel Corporation
+ *
+ * Authors:
+ * Yang Zhong<yang.zhong@intel.com>
+ * Sean Christopherson <sean.j.christopherson@intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "hw/i386/pc.h"
+#include "hw/i386/sgx-epc.h"
+#include "hw/mem/memory-device.h"
+#include "monitor/qdev.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
+
+static int sgx_epc_set_property(void *opaque, const char *name,
+ const char *value, Error **errp)
+{
+ Object *obj = opaque;
+ Error *err = NULL;
+
+ object_property_parse(obj, name, value, &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return -1;
+ }
+ return 0;
+}
+
+void pc_machine_init_sgx_epc(PCMachineState *pcms)
+{
+ SGXEPCState *sgx_epc;
+ X86MachineState *x86ms = X86_MACHINE(pcms);
+ MachineState *ms = MACHINE(qdev_get_machine());
+ Error *err = NULL;
+ strList *mdev = NULL;
+ strList *id = NULL;
+ Object *obj;
+
+ sgx_epc = g_malloc0(sizeof(*sgx_epc));
+ pcms->sgx_epc = sgx_epc;
+
+ sgx_epc->base = 0x100000000ULL + x86ms->above_4g_mem_size;
+
+ memory_region_init(&sgx_epc->mr, OBJECT(pcms), "sgx-epc", UINT64_MAX);
+ memory_region_add_subregion(get_system_memory(), sgx_epc->base,
+ &sgx_epc->mr);
+
+ for (mdev = ms->sgx_epc.memdev, id = ms->sgx_epc.id; mdev;
+ mdev = mdev->next, id = id->next) {
+ obj = object_new("sgx-epc");
+ qdev_set_id(DEVICE(obj), id->value);
+
+ /* set the memdev link with memory backend */
+ sgx_epc_set_property(obj, SGX_EPC_MEMDEV_PROP, mdev->value, &err);
+ object_property_set_bool(obj, "realized", true, &err);
+ object_unref(obj);
+ }
+
+ if ((sgx_epc->base + sgx_epc->size) < sgx_epc->base) {
+ error_report("Size of all 'sgx-epc' =0x%"PRIu64" causes EPC to wrap",
+ sgx_epc->size);
+ exit(EXIT_FAILURE);
+ }
+
+ memory_region_set_size(&sgx_epc->mr, sgx_epc->size);
+}
@@ -332,6 +332,7 @@ struct MachineState {
AccelState *accelerator;
CPUArchIdList *possible_cpus;
CpuTopology smp;
+ SgxEPC sgx_epc;
struct NVDIMMState *nvdimms_state;
struct NumaState *numa_state;
};
@@ -12,6 +12,7 @@
#include "hw/acpi/acpi_dev_interface.h"
#include "hw/hotplug.h"
#include "qom/object.h"
+#include "hw/i386/sgx-epc.h"
#define HPET_INTCAP "hpet-intcap"
@@ -52,6 +53,8 @@ typedef struct PCMachineState {
/* ACPI Memory hotplug IO base address */
hwaddr memhp_io_base;
+
+ SGXEPCState *sgx_epc;
} PCMachineState;
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
@@ -197,6 +200,9 @@ void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
extern GlobalProperty pc_compat_6_0[];
extern const size_t pc_compat_6_0_len;
+/* sgx-epc.c */
+void pc_machine_init_sgx_epc(PCMachineState *pcms);
+
extern GlobalProperty pc_compat_5_2[];
extern const size_t pc_compat_5_2_len;
@@ -41,4 +41,18 @@ typedef struct SGXEPCDevice {
HostMemoryBackend *hostmem;
} SGXEPCDevice;
+/*
+ * @base: address in guest physical address space where EPC regions start
+ * @mr: address space container for memory devices
+ */
+typedef struct SGXEPCState {
+ uint64_t base;
+ uint64_t size;
+
+ MemoryRegion mr;
+
+ struct SGXEPCDevice **sections;
+ int nr_sections;
+} SGXEPCState;
+
#endif
@@ -1194,6 +1194,23 @@
}
}
+##
+# @SgxEPC:
+#
+# Sgx EPC cmdline information
+#
+# @id: device's ID
+#
+# @memdev: memory backend linked with device
+#
+# Since: 6.1
+##
+{ 'struct': 'SgxEPC',
+ 'data': { 'id': [ 'str' ],
+ 'memdev': [ 'str' ]
+ }
+}
+
##
# @MemoryDeviceInfo:
#
@@ -122,8 +122,14 @@ SRST
-m 512M
ERST
-HXCOMM Deprecated by -machine
-DEF("M", HAS_ARG, QEMU_OPTION_M, "", QEMU_ARCH_ALL)
+DEF("M", HAS_ARG, QEMU_OPTION_M,
+ " sgx-epc.id.0=epcid,sgx-epc.memdev.0=memid\n",
+ QEMU_ARCH_ALL)
+
+SRST
+``sgx-epc.id.0=@var{epcid},sgx-epc.memdev.0=@var{memid}``
+ Define an SGX EPC section.
+ERST
DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
"-cpu cpu select CPU ('-cpu help' for list)\n", QEMU_ARCH_ALL)