diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-11-11 09:56:22 +0100 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-11-11 09:56:22 +0100 |
commit | 1b9fc6d8ba6667ceb56a3392e84656dcaed0d676 (patch) | |
tree | a142544cdc38101f4fce74135b86f58159e3c24c /hw | |
parent | b30187ef02d786da674cd80079e2fcd6bb8f85e1 (diff) | |
parent | 2c3132279b9a962c27adaea53b4c8e8480385706 (diff) | |
download | qemu-1b9fc6d8ba6667ceb56a3392e84656dcaed0d676.zip qemu-1b9fc6d8ba6667ceb56a3392e84656dcaed0d676.tar.gz qemu-1b9fc6d8ba6667ceb56a3392e84656dcaed0d676.tar.bz2 |
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* Fixes for SGX
* force_rcu notifiers
# gpg: Signature made Wed 10 Nov 2021 10:57:48 PM CET
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
sgx: Reset the vEPC regions during VM reboot
numa: avoid crash with SGX and "info numa"
accel/tcg: Register a force_rcu notifier
rcu: Introduce force_rcu notifier
target/i386: sgx: mark device not user creatable
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/core/numa.c | 7 | ||||
-rw-r--r-- | hw/i386/sgx-epc.c | 1 | ||||
-rw-r--r-- | hw/i386/sgx.c | 50 |
3 files changed, 58 insertions, 0 deletions
diff --git a/hw/core/numa.c b/hw/core/numa.c index 510d096..e6050b2 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -756,6 +756,7 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) PCDIMMDeviceInfo *pcdimm_info; VirtioPMEMDeviceInfo *vpi; VirtioMEMDeviceInfo *vmi; + SgxEPCDeviceInfo *se; for (info = info_list; info; info = info->next) { MemoryDeviceInfo *value = info->value; @@ -781,6 +782,12 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) node_mem[vmi->node].node_mem += vmi->size; node_mem[vmi->node].node_plugged_mem += vmi->size; break; + case MEMORY_DEVICE_INFO_KIND_SGX_EPC: + se = value->u.sgx_epc.data; + /* TODO: once we support numa, assign to right node */ + node_mem[0].node_mem += se->size; + node_mem[0].node_plugged_mem += se->size; + break; default: g_assert_not_reached(); } diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c index 55e2217..e508827 100644 --- a/hw/i386/sgx-epc.c +++ b/hw/i386/sgx-epc.c @@ -154,6 +154,7 @@ static void sgx_epc_class_init(ObjectClass *oc, void *data) dc->realize = sgx_epc_realize; dc->unrealize = sgx_epc_unrealize; dc->desc = "SGX EPC section"; + dc->user_creatable = false; device_class_set_props(dc, sgx_epc_properties); mdc->get_addr = sgx_epc_md_get_addr; diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c index 1160756..8fef3dd 100644 --- a/hw/i386/sgx.c +++ b/hw/i386/sgx.c @@ -21,6 +21,8 @@ #include "qapi/qapi-commands-misc-target.h" #include "exec/address-spaces.h" #include "sysemu/hw_accel.h" +#include "sysemu/reset.h" +#include <sys/ioctl.h> #define SGX_MAX_EPC_SECTIONS 8 #define SGX_CPUID_EPC_INVALID 0x0 @@ -29,6 +31,11 @@ #define SGX_CPUID_EPC_SECTION 0x1 #define SGX_CPUID_EPC_MASK 0xF +#define SGX_MAGIC 0xA4 +#define SGX_IOC_VEPC_REMOVE_ALL _IO(SGX_MAGIC, 0x04) + +#define RETRY_NUM 2 + static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) { return (low & MAKE_64BIT_MASK(12, 20)) + @@ -59,6 +66,46 @@ static uint64_t sgx_calc_host_epc_section_size(void) return size; } +static void sgx_epc_reset(void *opaque) +{ + PCMachineState *pcms = PC_MACHINE(qdev_get_machine()); + HostMemoryBackend *hostmem; + SGXEPCDevice *epc; + int failures; + int fd, i, j, r; + static bool warned = false; + + /* + * The second pass is needed to remove SECS pages that could not + * be removed during the first. + */ + for (i = 0; i < RETRY_NUM; i++) { + failures = 0; + for (j = 0; j < pcms->sgx_epc.nr_sections; j++) { + epc = pcms->sgx_epc.sections[j]; + hostmem = MEMORY_BACKEND(epc->hostmem); + fd = memory_region_get_fd(host_memory_backend_get_memory(hostmem)); + + r = ioctl(fd, SGX_IOC_VEPC_REMOVE_ALL); + if (r == -ENOTTY && !warned) { + warned = true; + warn_report("kernel does not support SGX_IOC_VEPC_REMOVE_ALL"); + warn_report("SGX might operate incorrectly in the guest after reset"); + break; + } else if (r > 0) { + /* SECS pages remain */ + failures++; + if (i == 1) { + error_report("cannot reset vEPC section %d", j); + } + } + } + if (!failures) { + break; + } + } +} + SGXInfo *qmp_query_sgx_capabilities(Error **errp) { SGXInfo *info = NULL; @@ -190,4 +237,7 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms) } memory_region_set_size(&sgx_epc->mr, sgx_epc->size); + + /* register the reset callback for sgx epc */ + qemu_register_reset(sgx_epc_reset, NULL); } |