[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 04/32] i386: Add 'sgx-epc' device to expose EPC sections to guest
From: |
Yang Zhong |
Subject: |
[PATCH 04/32] i386: Add 'sgx-epc' device to expose EPC sections to guest |
Date: |
Mon, 19 Apr 2021 18:01:28 +0800 |
From: Sean Christopherson <sean.j.christopherson@intel.com>
SGX EPC is enumerated through CPUID, i.e. EPC "devices" need to be
realized prior to realizing the vCPUs themselves, which occurs long
before generic devices are parsed and realized. Because of this,
do not allow 'sgx-epc' devices to be instantiated after vCPUS have
been created.
The 'sgx-epc' device is essentially a placholder at this time, it will
be fully implemented in a future patch along with a dedicated command
to create 'sgx-epc' devices.
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Yang Zhong <yang.zhong@intel.com>
---
hw/i386/meson.build | 1 +
hw/i386/sgx-epc.c | 161 ++++++++++++++++++++++++++++++++++++++
include/hw/i386/sgx-epc.h | 44 +++++++++++
3 files changed, 206 insertions(+)
create mode 100644 hw/i386/sgx-epc.c
create mode 100644 include/hw/i386/sgx-epc.h
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index e5d109f5c6..087426c75c 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -5,6 +5,7 @@ i386_ss.add(files(
'e820_memory_layout.c',
'multiboot.c',
'x86.c',
+ 'sgx-epc.c',
))
i386_ss.add(when: 'CONFIG_X86_IOMMU', if_true: files('x86-iommu.c'),
diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c
new file mode 100644
index 0000000000..aa487dea79
--- /dev/null
+++ b/hw/i386/sgx-epc.c
@@ -0,0 +1,161 @@
+/*
+ * SGX EPC device
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * Authors:
+ * 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 "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"
+
+static Property sgx_epc_properties[] = {
+ DEFINE_PROP_UINT64(SGX_EPC_ADDR_PROP, SGXEPCDevice, addr, 0),
+ DEFINE_PROP_LINK(SGX_EPC_MEMDEV_PROP, SGXEPCDevice, hostmem,
+ TYPE_MEMORY_BACKEND, HostMemoryBackend *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sgx_epc_get_size(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ Error *local_err = NULL;
+ uint64_t value;
+
+ value = memory_device_get_region_size(MEMORY_DEVICE(obj), &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ visit_type_uint64(v, name, &value, errp);
+}
+
+static void sgx_epc_init(Object *obj)
+{
+ object_property_add(obj, SGX_EPC_SIZE_PROP, "uint64", sgx_epc_get_size,
+ NULL, NULL, NULL);
+}
+
+static void sgx_epc_realize(DeviceState *dev, Error **errp)
+{
+ PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+ X86MachineState *x86ms = X86_MACHINE(pcms);
+ SGXEPCDevice *epc = SGX_EPC(dev);
+ const char *path;
+
+ if (x86ms->boot_cpus != 0) {
+ error_setg(errp, "'" TYPE_SGX_EPC "' can't be created after vCPUs,"
+ "e.g. via -device");
+ return;
+ }
+
+ if (!epc->hostmem) {
+ error_setg(errp, "'" SGX_EPC_MEMDEV_PROP "' property is not set");
+ return;
+ } else if (host_memory_backend_is_mapped(epc->hostmem)) {
+ path = object_get_canonical_path_component(OBJECT(epc->hostmem));
+ error_setg(errp, "can't use already busy memdev: %s", path);
+ return;
+ }
+
+ error_setg(errp, "'" TYPE_SGX_EPC "' not supported");
+}
+
+static void sgx_epc_unrealize(DeviceState *dev)
+{
+ SGXEPCDevice *epc = SGX_EPC(dev);
+
+ host_memory_backend_set_mapped(epc->hostmem, false);
+}
+
+static uint64_t sgx_epc_md_get_addr(const MemoryDeviceState *md)
+{
+ const SGXEPCDevice *epc = SGX_EPC(md);
+
+ return epc->addr;
+}
+
+static void sgx_epc_md_set_addr(MemoryDeviceState *md, uint64_t addr,
+ Error **errp)
+{
+ object_property_set_uint(OBJECT(md), SGX_EPC_ADDR_PROP, addr, errp);
+}
+
+static uint64_t sgx_epc_md_get_plugged_size(const MemoryDeviceState *md,
+ Error **errp)
+{
+ return 0;
+}
+
+static MemoryRegion *sgx_epc_md_get_memory_region(MemoryDeviceState *md,
+ Error **errp)
+{
+ SGXEPCDevice *epc = SGX_EPC(md);
+
+ if (!epc->hostmem) {
+ error_setg(errp, "'" SGX_EPC_MEMDEV_PROP "' property must be set");
+ return NULL;
+ }
+
+ return host_memory_backend_get_memory(epc->hostmem);
+}
+
+static void sgx_epc_md_fill_device_info(const MemoryDeviceState *md,
+ MemoryDeviceInfo *info)
+{
+ /* TODO */
+}
+
+static void sgx_epc_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
+
+ dc->hotpluggable = false;
+ dc->realize = sgx_epc_realize;
+ dc->unrealize = sgx_epc_unrealize;
+ dc->desc = "SGX EPC section";
+ device_class_set_props(dc, sgx_epc_properties);
+
+ mdc->get_addr = sgx_epc_md_get_addr;
+ mdc->set_addr = sgx_epc_md_set_addr;
+ mdc->get_plugged_size = sgx_epc_md_get_plugged_size;
+ mdc->get_memory_region = sgx_epc_md_get_memory_region;
+ mdc->fill_device_info = sgx_epc_md_fill_device_info;
+}
+
+static TypeInfo sgx_epc_info = {
+ .name = TYPE_SGX_EPC,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(SGXEPCDevice),
+ .instance_init = sgx_epc_init,
+ .class_init = sgx_epc_class_init,
+ .class_size = sizeof(DeviceClass),
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_MEMORY_DEVICE },
+ { }
+ },
+};
+
+static void sgx_epc_register_types(void)
+{
+ type_register_static(&sgx_epc_info);
+}
+
+type_init(sgx_epc_register_types)
diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h
new file mode 100644
index 0000000000..5fd9ae2d0c
--- /dev/null
+++ b/include/hw/i386/sgx-epc.h
@@ -0,0 +1,44 @@
+/*
+ * SGX EPC device
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * Authors:
+ * 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.
+ */
+#ifndef QEMU_SGX_EPC_H
+#define QEMU_SGX_EPC_H
+
+#include "sysemu/hostmem.h"
+
+#define TYPE_SGX_EPC "sgx-epc"
+#define SGX_EPC(obj) \
+ OBJECT_CHECK(SGXEPCDevice, (obj), TYPE_SGX_EPC)
+#define SGX_EPC_CLASS(oc) \
+ OBJECT_CLASS_CHECK(SGXEPCDeviceClass, (oc), TYPE_SGX_EPC)
+#define SGX_EPC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(SGXEPCDeviceClass, (obj), TYPE_SGX_EPC)
+
+#define SGX_EPC_ADDR_PROP "addr"
+#define SGX_EPC_SIZE_PROP "size"
+#define SGX_EPC_MEMDEV_PROP "memdev"
+
+/**
+ * SGXEPCDevice:
+ * @addr: starting guest physical address, where @SGXEPCDevice is mapped.
+ * Default value: 0, means that address is auto-allocated.
+ * @hostmem: host memory backend providing memory for @SGXEPCDevice
+ */
+typedef struct SGXEPCDevice {
+ /* private */
+ DeviceState parent_obj;
+
+ /* public */
+ uint64_t addr;
+ HostMemoryBackend *hostmem;
+} SGXEPCDevice;
+
+#endif
--
2.29.2.334.gfaefdd61ec
- [PATCH 00/32] Qemu SGX virtualization, Yang Zhong, 2021/04/19
- [PATCH 02/32] hostmem: Add hostmem-epc as a backend for SGX EPC, Yang Zhong, 2021/04/19
- [PATCH 01/32] memory: Add RAM_PROTECTED flag to skip IOMMU mappings, Yang Zhong, 2021/04/19
- [PATCH 03/32] qom: Add memory-backend-epc ObjectOptions support, Yang Zhong, 2021/04/19
- [PATCH 04/32] i386: Add 'sgx-epc' device to expose EPC sections to guest,
Yang Zhong <=
- [PATCH 08/32] i386: Add SGX CPUID leaf FEAT_SGX_12_0_EBX, Yang Zhong, 2021/04/19
- [PATCH 06/32] i386: Add primary SGX CPUID and MSR defines, Yang Zhong, 2021/04/19
- [PATCH 05/32] vl: Add "sgx-epc" option to expose SGX EPC sections to guest, Yang Zhong, 2021/04/19
- [PATCH 09/32] i386: Add SGX CPUID leaf FEAT_SGX_12_1_EAX, Yang Zhong, 2021/04/19
- [PATCH 10/32] i386: Add get/set/migrate support for SGX_LEPUBKEYHASH MSRs, Yang Zhong, 2021/04/19
- [PATCH 07/32] i386: Add SGX CPUID leaf FEAT_SGX_12_0_EAX, Yang Zhong, 2021/04/19
- [PATCH 12/32] i386: Update SGX CPUID info according to hardware/KVM/user input, Yang Zhong, 2021/04/19
- [PATCH 11/32] i386: Add feature control MSR dependency when SGX is enabled, Yang Zhong, 2021/04/19
- [PATCH 13/32] linux-headers: Add placeholder for KVM_CAP_SGX_ATTRIBUTE, Yang Zhong, 2021/04/19