qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Yang Zhong <yang.zhong@intel.com>,
	Sean Christopherson <sean.j.christopherson@intel.com>
Subject: [PULL v4 13/43] vl: Add sgx compound properties to expose SGX EPC sections to guest
Date: Wed,  8 Sep 2021 12:03:56 +0200	[thread overview]
Message-ID: <20210908100426.264356-14-pbonzini@redhat.com> (raw)
In-Reply-To: <20210908100426.264356-1-pbonzini@redhat.com>

From: Sean Christopherson <sean.j.christopherson@intel.com>

Because SGX EPC is enumerated through CPUID, EPC "devices" need to be
realized prior to realizing the vCPUs themselves, i.e. long before
generic devices are parsed and realized.  From a virtualization
perspective, the CPUID aspect also means that EPC sections cannot be
hotplugged without paravirtualizing the guest kernel (hardware does
not support hotplugging as EPC sections must be locked down during
pre-boot to provide EPC's security properties).

So even though EPC sections could be realized through the generic
-devices command, they need to be created much earlier for them to
actually be usable by the guest.  Place all EPC sections in a
contiguous block, somewhat arbitrarily starting after RAM above 4g.
Ensuring EPC is in a contiguous region simplifies calculations, e.g.
device memory base, PCI hole, etc..., allows dynamic calculation of the
total EPC size, e.g. exposing EPC to guests does not require -maxmem,
and last but not least allows all of EPC to be enumerated in a single
ACPI entry, which is expected by some kernels, e.g. Windows 7 and 8.

The new compound properties command for sgx like below:
 ......
 -object memory-backend-epc,id=mem1,size=28M,prealloc=on \
 -object memory-backend-epc,id=mem2,size=10M \
 -M sgx-epc.0.memdev=mem1,sgx-epc.1.memdev=mem2

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Yang Zhong <yang.zhong@intel.com>

v3-->v4:
  - Moved sgx compound property setter/getter from MachineState
    to X86MachineState(Paolo).
  - Re-defined struct SgxEPC, removed 'id' property and added struct
    SgxEPCList for sgx-epc.0.{memdev}(Paolo).
  - Removed g_malloc0(), and changed the 'SGXEPCState *sgx_epc' to
    'SGXEPCState sgx_epc' in struct PCMachineState(Paolo).
  - Changed the SGX compound property cmdline from sgx-epc.{memdev}.0
    to sgx-epc.0.{memdev}(Paolo).

v2-->v3:
   - Removed the QemuOptsList for sgx-epc virtual device and used the '-M' to
     replace '-sgx-epc' with compound properties(Paolo).
Message-Id: <20210719112136.57018-6-yang.zhong@intel.com>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/meson.build       |  1 +
 hw/i386/sgx-epc.c         | 20 ++++++++----
 hw/i386/sgx.c             | 67 +++++++++++++++++++++++++++++++++++++++
 hw/i386/x86.c             | 29 +++++++++++++++++
 include/hw/i386/pc.h      |  6 ++++
 include/hw/i386/sgx-epc.h | 14 ++++++++
 include/hw/i386/x86.h     |  1 +
 qapi/machine.json         | 26 +++++++++++++++
 qemu-options.hx           | 10 ++++--
 9 files changed, 166 insertions(+), 8 deletions(-)
 create mode 100644 hw/i386/sgx.c

diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index 27476b36bb..fefce9e4ba 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -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'),
diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c
index aa487dea79..924dea22f0 100644
--- a/hw/i386/sgx-epc.c
+++ b/hw/i386/sgx-epc.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)
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
new file mode 100644
index 0000000000..e77deb0b00
--- /dev/null
+++ b/hw/i386/sgx.c
@@ -0,0 +1,67 @@
+/*
+ * 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 = &pcms->sgx_epc;
+    X86MachineState *x86ms = X86_MACHINE(pcms);
+    Error *err = NULL;
+    SgxEPCList *list = NULL;
+    Object *obj;
+
+    memset(sgx_epc, 0, sizeof(SGXEPCState));
+    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 (list = x86ms->sgx_epc_list; list; list = list->next) {
+        obj = object_new("sgx-epc");
+
+        /* set the memdev link with memory backend */
+        sgx_epc_set_property(obj, SGX_EPC_MEMDEV_PROP, list->value->memdev,
+                             &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);
+}
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 00448ed55a..41ef9a84a9 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -30,6 +30,8 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qapi-visit-common.h"
+#include "qapi/clone-visitor.h"
+#include "qapi/qapi-visit-machine.h"
 #include "qapi/visitor.h"
 #include "sysemu/qtest.h"
 #include "sysemu/whpx.h"
@@ -1263,6 +1265,27 @@ static void x86_machine_set_bus_lock_ratelimit(Object *obj, Visitor *v,
     visit_type_uint64(v, name, &x86ms->bus_lock_ratelimit, errp);
 }
 
+static void machine_get_sgx_epc(Object *obj, Visitor *v, const char *name,
+                                void *opaque, Error **errp)
+{
+    X86MachineState *x86ms = X86_MACHINE(obj);
+    SgxEPCList *list = x86ms->sgx_epc_list;
+
+    visit_type_SgxEPCList(v, name, &list, errp);
+}
+
+static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name,
+                                void *opaque, Error **errp)
+{
+    X86MachineState *x86ms = X86_MACHINE(obj);
+    SgxEPCList *list;
+
+    list = x86ms->sgx_epc_list;
+    visit_type_SgxEPCList(v, name, &x86ms->sgx_epc_list, errp);
+
+    qapi_free_SgxEPCList(list);
+}
+
 static void x86_machine_initfn(Object *obj)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
@@ -1322,6 +1345,12 @@ static void x86_machine_class_init(ObjectClass *oc, void *data)
                                 x86_machine_set_bus_lock_ratelimit, NULL, NULL);
     object_class_property_set_description(oc, X86_MACHINE_BUS_LOCK_RATELIMIT,
             "Set the ratelimit for the bus locks acquired in VMs");
+
+    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 const TypeInfo x86_machine_info = {
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 4d2e35a152..f2869437ab 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -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"
 
@@ -49,6 +50,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"
@@ -198,6 +201,9 @@ extern const size_t pc_compat_6_1_len;
 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;
 
diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h
index 5fd9ae2d0c..2b2490892b 100644
--- a/include/hw/i386/sgx-epc.h
+++ b/include/hw/i386/sgx-epc.h
@@ -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
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 6e9244a82c..23267a3674 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -62,6 +62,7 @@ struct X86MachineState {
     unsigned pci_irq_mask;
     unsigned apic_id_limit;
     uint16_t boot_cpus;
+    SgxEPCList *sgx_epc_list;
 
     OnOffAuto smm;
     OnOffAuto acpi;
diff --git a/qapi/machine.json b/qapi/machine.json
index 157712f006..10d36da83f 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1194,6 +1194,32 @@
           }
 }
 
+##
+# @SgxEPC:
+#
+# Sgx EPC cmdline information
+#
+# @memdev: memory backend linked with device
+#
+# Since: 6.1
+##
+{ 'struct': 'SgxEPC',
+  'data': { 'memdev': 'str' }
+}
+
+##
+# @SgxEPCProperties:
+#
+# Properties for SgxEPC objects.
+#
+# @sgx-epc: sgx epc section properties.
+#
+# Since: 6.1
+##
+{ 'struct': 'SgxEPCProperties',
+  'data': { 'sgx-epc': ['SgxEPC'] }
+}
+
 ##
 # @MemoryDeviceInfo:
 #
diff --git a/qemu-options.hx b/qemu-options.hx
index 8f603cc7e6..ceca52818a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -126,8 +126,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.0.memdev=memid\n",
+    QEMU_ARCH_ALL)
+
+SRST
+``sgx-epc.0.memdev=@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)
-- 
2.31.1




  parent reply	other threads:[~2021-09-08 10:17 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-08 10:03 [PULL v4 00/43] (Mostly) x86 changes for 2021-09-06 Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 01/43] target/i386: add missing bits to CR4_RESERVED_MASK Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 02/43] target/i386: VMRUN and VMLOAD canonicalizations Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 03/43] target/i386: Added VGIF feature Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 04/43] target/i386: Moved int_ctl into CPUX86State structure Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 05/43] target/i386: Added VGIF V_IRQ masking capability Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 06/43] target/i386: Added ignore TPR check in ctl_has_irq Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 07/43] target/i386: Added changed priority check for VIRQ Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 08/43] target/i386: Added vVMLOAD and vVMSAVE feature Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 09/43] memory: Add RAM_PROTECTED flag to skip IOMMU mappings Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 10/43] hostmem: Add hostmem-epc as a backend for SGX EPC Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 11/43] qom: Add memory-backend-epc ObjectOptions support Paolo Bonzini
2021-09-08 14:51   ` Eric Blake
2021-09-08 10:03 ` [PULL v4 12/43] i386: Add 'sgx-epc' device to expose EPC sections to guest Paolo Bonzini
2021-09-08 10:03 ` Paolo Bonzini [this message]
2021-09-08 14:52   ` [PULL v4 13/43] vl: Add sgx compound properties to expose SGX " Eric Blake
2021-09-09  3:01     ` Yang Zhong
2021-09-08 10:03 ` [PULL v4 14/43] i386: Add primary SGX CPUID and MSR defines Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 15/43] i386: Add SGX CPUID leaf FEAT_SGX_12_0_EAX Paolo Bonzini
2021-09-08 10:03 ` [PULL v4 16/43] i386: Add SGX CPUID leaf FEAT_SGX_12_0_EBX Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 17/43] i386: Add SGX CPUID leaf FEAT_SGX_12_1_EAX Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 18/43] i386: Add get/set/migrate support for SGX_LEPUBKEYHASH MSRs Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 19/43] fw_cfg: add etc/msr_feature_control Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 20/43] i386: Add feature control MSR dependency when SGX is enabled Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 21/43] i386: Update SGX CPUID info according to hardware/KVM/user input Paolo Bonzini
2021-09-09 13:09   ` Philippe Mathieu-Daudé
2021-09-08 10:04 ` [PULL v4 22/43] i386: kvm: Add support for exposing PROVISIONKEY to guest Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 23/43] i386: Propagate SGX CPUID sub-leafs to KVM Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 24/43] Adjust min CPUID level to 0x12 when SGX is enabled Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 25/43] hw/i386/fw_cfg: Set SGX bits in feature control fw_cfg accordingly Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 26/43] hw/i386/pc: Account for SGX EPC sections when calculating device memory Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 27/43] i386/pc: Add e820 entry for SGX EPC section(s) Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 28/43] i386: acpi: Add SGX EPC entry to ACPI tables Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 29/43] q35: Add support for SGX EPC Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 30/43] i440fx: " Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 31/43] hostmem-epc: Add the reset interface for EPC backend reset Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 32/43] sgx-epc: Add the reset interface for sgx-epc virt device Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 33/43] sgx-epc: Avoid bios reset during sgx epc initialization Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 34/43] hostmem-epc: Make prealloc consistent with qemu cmdline during reset Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 35/43] Kconfig: Add CONFIG_SGX support Paolo Bonzini
2021-09-09 13:16   ` Philippe Mathieu-Daudé
2021-09-09 13:33     ` Philippe Mathieu-Daudé
2021-09-08 10:04 ` [PULL v4 36/43] sgx-epc: Add the fill_device_info() callback support Paolo Bonzini
2021-09-08 14:54   ` Eric Blake
2021-09-08 10:04 ` [PULL v4 37/43] docs: standardize book titles to === with overline Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 38/43] docs: standardize directory index to --- " Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 39/43] docs/system: standardize man page sections " Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 40/43] docs/system: move x86 CPU configuration to a separate document Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 41/43] docs/system: Add SGX documentation to the system manual Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 42/43] meson.build: Do not look for VNC-related libraries if have_system is not set Paolo Bonzini
2021-09-08 10:04 ` [PULL v4 43/43] ebpf: only include in system emulators Paolo Bonzini
2021-09-09 13:25 ` [PULL v4 00/43] (Mostly) x86 changes for 2021-09-06 Peter Maydell
2021-09-09 13:32   ` Philippe Mathieu-Daudé
2021-09-11 12:59 ` Peter Maydell
2021-09-11 13:05   ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210908100426.264356-14-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=sean.j.christopherson@intel.com \
    --cc=yang.zhong@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).