diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-09-30 17:38:30 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-09-30 17:38:31 +0100 |
commit | 0021c4765a6b83e5b09409b75d50c6caaa6971b9 (patch) | |
tree | 2d753cd2cc80d8e4ea0e3469b4334bace179c0b4 /target | |
parent | fce8f7735fcea23056ff41be55e73eacbca31b5e (diff) | |
parent | c1de5858bd39b299d3d8baec38b0376bed7f19e8 (diff) | |
download | qemu-0021c4765a6b83e5b09409b75d50c6caaa6971b9.zip qemu-0021c4765a6b83e5b09409b75d50c6caaa6971b9.tar.gz qemu-0021c4765a6b83e5b09409b75d50c6caaa6971b9.tar.bz2 |
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* SGX implementation for x86
* Miscellaneous bugfixes
* Fix dependencies from ROMs to qtests
# gpg: Signature made Thu 30 Sep 2021 14:30:35 BST
# 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]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini-gitlab/tags/for-upstream: (33 commits)
meson_options.txt: Switch the default value for the vnc option to 'auto'
build-sys: add HAVE_IPPROTO_MPTCP
memory: Add tracepoint for dirty sync
memory: Name all the memory listeners
target/i386: Fix memory leak in sev_read_file_base64()
tests: qtest: bios-tables-test depends on the unpacked edk2 ROMs
meson: unpack edk2 firmware even if --disable-blobs
target/i386: Add the query-sgx-capabilities QMP command
target/i386: Add HMP and QMP interfaces for SGX
docs/system: Add SGX documentation to the system manual
sgx-epc: Add the fill_device_info() callback support
i440fx: Add support for SGX EPC
q35: Add support for SGX EPC
i386: acpi: Add SGX EPC entry to ACPI tables
i386/pc: Add e820 entry for SGX EPC section(s)
hw/i386/pc: Account for SGX EPC sections when calculating device memory
hw/i386/fw_cfg: Set SGX bits in feature control fw_cfg accordingly
Adjust min CPUID level to 0x12 when SGX is enabled
i386: Propagate SGX CPUID sub-leafs to KVM
i386: kvm: Add support for exposing PROVISIONKEY to guest
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/kvm.c | 1 | ||||
-rw-r--r-- | target/i386/cpu.c | 167 | ||||
-rw-r--r-- | target/i386/cpu.h | 16 | ||||
-rw-r--r-- | target/i386/hax/hax-mem.c | 1 | ||||
-rw-r--r-- | target/i386/kvm/kvm.c | 77 | ||||
-rw-r--r-- | target/i386/kvm/kvm_i386.h | 2 | ||||
-rw-r--r-- | target/i386/machine.c | 20 | ||||
-rw-r--r-- | target/i386/monitor.c | 32 | ||||
-rw-r--r-- | target/i386/nvmm/nvmm-all.c | 1 | ||||
-rw-r--r-- | target/i386/sev.c | 2 | ||||
-rw-r--r-- | target/i386/whpx/whpx-all.c | 1 |
11 files changed, 315 insertions, 5 deletions
diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 94b970b..bbf1ce7 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -335,6 +335,7 @@ static void kvm_arm_devlistener_del(MemoryListener *listener, } static MemoryListener devlistener = { + .name = "kvm-arm", .region_add = kvm_arm_devlistener_add, .region_del = kvm_arm_devlistener_del, }; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6b029f1..cacec60 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -36,6 +36,7 @@ #ifndef CONFIG_USER_ONLY #include "exec/address-spaces.h" #include "hw/boards.h" +#include "hw/i386/sgx-epc.h" #endif #include "disas/capstone.h" @@ -654,6 +655,9 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, /* missing: CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */ #define TCG_14_0_ECX_FEATURES 0 +#define TCG_SGX_12_0_EAX_FEATURES 0 +#define TCG_SGX_12_0_EBX_FEATURES 0 +#define TCG_SGX_12_1_EAX_FEATURES 0 FeatureWordInfo feature_word_info[FEATURE_WORDS] = { [FEAT_1_EDX] = { @@ -795,7 +799,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { [FEAT_7_0_EBX] = { .type = CPUID_FEATURE_WORD, .feat_names = { - "fsgsbase", "tsc-adjust", NULL, "bmi1", + "fsgsbase", "tsc-adjust", "sgx", "bmi1", "hle", "avx2", NULL, "smep", "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL, @@ -821,7 +825,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "la57", NULL, NULL, NULL, NULL, NULL, "rdpid", NULL, "bus-lock-detect", "cldemote", NULL, "movdiri", - "movdir64b", NULL, NULL, "pks", + "movdir64b", NULL, "sgxlc", "pks", }, .cpuid = { .eax = 7, @@ -1182,6 +1186,65 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { .tcg_features = TCG_14_0_ECX_FEATURES, }, + [FEAT_SGX_12_0_EAX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { + "sgx1", "sgx2", NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + }, + .cpuid = { + .eax = 0x12, + .needs_ecx = true, .ecx = 0, + .reg = R_EAX, + }, + .tcg_features = TCG_SGX_12_0_EAX_FEATURES, + }, + + [FEAT_SGX_12_0_EBX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { + "sgx-exinfo" , NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + }, + .cpuid = { + .eax = 0x12, + .needs_ecx = true, .ecx = 0, + .reg = R_EBX, + }, + .tcg_features = TCG_SGX_12_0_EBX_FEATURES, + }, + + [FEAT_SGX_12_1_EAX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { + NULL, "sgx-debug", "sgx-mode64", NULL, + "sgx-provisionkey", "sgx-tokenkey", NULL, "sgx-kss", + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + }, + .cpuid = { + .eax = 0x12, + .needs_ecx = true, .ecx = 1, + .reg = R_EAX, + }, + .tcg_features = TCG_SGX_12_1_EAX_FEATURES, + }, }; typedef struct FeatureMask { @@ -5272,6 +5335,25 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx |= CPUID_7_0_ECX_OSPKE; } *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */ + + /* + * SGX cannot be emulated in software. If hardware does not + * support enabling SGX and/or SGX flexible launch control, + * then we need to update the VM's CPUID values accordingly. + */ + if ((*ebx & CPUID_7_0_EBX_SGX) && + (!kvm_enabled() || + !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_EBX) & + CPUID_7_0_EBX_SGX))) { + *ebx &= ~CPUID_7_0_EBX_SGX; + } + + if ((*ecx & CPUID_7_0_ECX_SGX_LC) && + (!(*ebx & CPUID_7_0_EBX_SGX) || !kvm_enabled() || + !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_ECX) & + CPUID_7_0_ECX_SGX_LC))) { + *ecx &= ~CPUID_7_0_ECX_SGX_LC; + } } else if (count == 1) { *eax = env->features[FEAT_7_1_EAX]; *ebx = 0; @@ -5407,6 +5489,66 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } break; } + case 0x12: +#ifndef CONFIG_USER_ONLY + if (!kvm_enabled() || + !(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SGX)) { + *eax = *ebx = *ecx = *edx = 0; + break; + } + + /* + * SGX sub-leafs CPUID.0x12.{0x2..N} enumerate EPC sections. Retrieve + * the EPC properties, e.g. confidentiality and integrity, from the + * host's first EPC section, i.e. assume there is one EPC section or + * that all EPC sections have the same security properties. + */ + if (count > 1) { + uint64_t epc_addr, epc_size; + + if (sgx_epc_get_section(count - 2, &epc_addr, &epc_size)) { + *eax = *ebx = *ecx = *edx = 0; + break; + } + host_cpuid(index, 2, eax, ebx, ecx, edx); + *eax = (uint32_t)(epc_addr & 0xfffff000) | 0x1; + *ebx = (uint32_t)(epc_addr >> 32); + *ecx = (uint32_t)(epc_size & 0xfffff000) | (*ecx & 0xf); + *edx = (uint32_t)(epc_size >> 32); + break; + } + + /* + * SGX sub-leafs CPUID.0x12.{0x0,0x1} are heavily dependent on hardware + * and KVM, i.e. QEMU cannot emulate features to override what KVM + * supports. Features can be further restricted by userspace, but not + * made more permissive. + */ + *eax = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EAX); + *ebx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EBX); + *ecx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_ECX); + *edx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EDX); + + if (count == 0) { + *eax &= env->features[FEAT_SGX_12_0_EAX]; + *ebx &= env->features[FEAT_SGX_12_0_EBX]; + } else { + *eax &= env->features[FEAT_SGX_12_1_EAX]; + *ebx &= 0; /* ebx reserve */ + *ecx &= env->features[FEAT_XSAVE_COMP_LO]; + *edx &= env->features[FEAT_XSAVE_COMP_HI]; + + /* FP and SSE are always allowed regardless of XSAVE/XCR0. */ + *ecx |= XSTATE_FP_MASK | XSTATE_SSE_MASK; + + /* Access to PROVISIONKEY requires additional credentials. */ + if ((*eax & (1U << 4)) && + !kvm_enable_sgx_provisioning(cs->kvm_state)) { + *eax &= ~(1U << 4); + } + } +#endif + break; case 0x14: { /* Intel Processor Trace Enumeration */ *eax = 0; @@ -5638,6 +5780,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } } +static void x86_cpu_set_sgxlepubkeyhash(CPUX86State *env) +{ +#ifndef CONFIG_USER_ONLY + /* Those default values are defined in Skylake HW */ + env->msr_ia32_sgxlepubkeyhash[0] = 0xa6053e051270b7acULL; + env->msr_ia32_sgxlepubkeyhash[1] = 0x6cfbe8ba8b3b413dULL; + env->msr_ia32_sgxlepubkeyhash[2] = 0xc4916d99f2b3735dULL; + env->msr_ia32_sgxlepubkeyhash[3] = 0xd4f8c05909f9bb3bULL; +#endif +} + static void x86_cpu_reset(DeviceState *dev) { CPUState *s = CPU(dev); @@ -5770,6 +5923,8 @@ static void x86_cpu_reset(DeviceState *dev) if (kvm_enabled()) { kvm_arch_reset_vcpu(cpu); } + + x86_cpu_set_sgxlepubkeyhash(env); #endif } @@ -5999,6 +6154,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) if (sev_enabled()) { x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000001F); } + + /* SGX requires CPUID[0x12] for EPC enumeration */ + if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SGX) { + x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x12); + } } /* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */ @@ -6152,6 +6312,8 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) & CPUID_EXT2_AMD_ALIASES); } + x86_cpu_set_sgxlepubkeyhash(env); + /* * note: the call to the framework needs to happen after feature expansion, * but before the checks/modifications to ucode_rev, mwait, phys_bits. @@ -6839,7 +7001,6 @@ static const TypeInfo x86_cpu_type_info = { .class_init = x86_cpu_common_class_init, }; - /* "base" CPU model, used by query-cpu-model-expansion */ static void x86_cpu_base_class_init(ObjectClass *oc, void *data) { diff --git a/target/i386/cpu.h b/target/i386/cpu.h index c2954c7..29552dc 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -389,9 +389,17 @@ typedef enum X86Seg { #define MSR_IA32_PKRS 0x6e1 #define FEATURE_CONTROL_LOCKED (1<<0) +#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1ULL << 1) #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) +#define FEATURE_CONTROL_SGX_LC (1ULL << 17) +#define FEATURE_CONTROL_SGX (1ULL << 18) #define FEATURE_CONTROL_LMCE (1<<20) +#define MSR_IA32_SGXLEPUBKEYHASH0 0x8c +#define MSR_IA32_SGXLEPUBKEYHASH1 0x8d +#define MSR_IA32_SGXLEPUBKEYHASH2 0x8e +#define MSR_IA32_SGXLEPUBKEYHASH3 0x8f + #define MSR_P6_PERFCTR0 0xc1 #define MSR_IA32_SMBASE 0x9e @@ -570,6 +578,9 @@ typedef enum FeatureWord { FEAT_VMX_BASIC, FEAT_VMX_VMFUNC, FEAT_14_0_ECX, + FEAT_SGX_12_0_EAX, /* CPUID[EAX=0x12,ECX=0].EAX (SGX) */ + FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */ + FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */ FEATURE_WORDS, } FeatureWord; @@ -718,6 +729,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; /* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */ #define CPUID_7_0_EBX_FSGSBASE (1U << 0) +/* Support SGX */ +#define CPUID_7_0_EBX_SGX (1U << 2) /* 1st Group of Advanced Bit Manipulation Extensions */ #define CPUID_7_0_EBX_BMI1 (1U << 3) /* Hardware Lock Elision */ @@ -805,6 +818,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_ECX_MOVDIRI (1U << 27) /* Move 64 Bytes as Direct Store Instruction */ #define CPUID_7_0_ECX_MOVDIR64B (1U << 28) +/* Support SGX Launch Control */ +#define CPUID_7_0_ECX_SGX_LC (1U << 30) /* Protection Keys for Supervisor-mode Pages */ #define CPUID_7_0_ECX_PKS (1U << 31) @@ -1501,6 +1516,7 @@ typedef struct CPUX86State { uint64_t mcg_status; uint64_t msr_ia32_misc_enable; uint64_t msr_ia32_feature_control; + uint64_t msr_ia32_sgxlepubkeyhash[4]; uint64_t msr_fixed_ctr_ctrl; uint64_t msr_global_ctrl; diff --git a/target/i386/hax/hax-mem.c b/target/i386/hax/hax-mem.c index 8d44edb..a226d17 100644 --- a/target/i386/hax/hax-mem.c +++ b/target/i386/hax/hax-mem.c @@ -285,6 +285,7 @@ static void hax_log_sync(MemoryListener *listener, } static MemoryListener hax_memory_listener = { + .name = "hax", .begin = hax_transaction_begin, .commit = hax_transaction_commit, .region_add = hax_region_add, diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 500d2e0..7f1b060 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -1703,6 +1703,25 @@ int kvm_arch_init_vcpu(CPUState *cs) } break; case 0x7: + case 0x12: + for (j = 0; ; j++) { + c->function = i; + c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + c->index = j; + cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx); + + if (j > 1 && (c->eax & 0xf) != 1) { + break; + } + + if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { + fprintf(stderr, "cpuid_data is full, no space for " + "cpuid(eax:0x12,ecx:0x%x)\n", j); + abort(); + } + c = &cpuid_data.entries[cpuid_i++]; + } + break; case 0x14: { uint32_t times; @@ -1877,6 +1896,11 @@ int kvm_arch_init_vcpu(CPUState *cs) !!(c->ecx & CPUID_EXT_SMX); } + c = cpuid_find_entry(&cpuid_data.cpuid, 7, 0); + if (c && (c->ebx & CPUID_7_0_EBX_SGX)) { + has_msr_feature_control = true; + } + if (env->mcg_cap & MCG_LMCE_P) { has_msr_mcg_ext_ctl = has_msr_feature_control = true; } @@ -2224,7 +2248,7 @@ static void register_smram_listener(Notifier *n, void *unused) address_space_init(&smram_address_space, &smram_as_root, "KVM-SMRAM"); kvm_memory_listener_register(kvm_state, &smram_listener, - &smram_address_space, 1); + &smram_address_space, 1, "kvm-smram"); } int kvm_arch_init(MachineState *ms, KVMState *s) @@ -3107,6 +3131,17 @@ static int kvm_put_msrs(X86CPU *cpu, int level) } } + if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_SGX_LC) { + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH0, + env->msr_ia32_sgxlepubkeyhash[0]); + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH1, + env->msr_ia32_sgxlepubkeyhash[1]); + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH2, + env->msr_ia32_sgxlepubkeyhash[2]); + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH3, + env->msr_ia32_sgxlepubkeyhash[3]); + } + /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see * kvm_put_msr_feature_control. */ } @@ -3446,6 +3481,13 @@ static int kvm_get_msrs(X86CPU *cpu) } } + if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_SGX_LC) { + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH0, 0); + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH1, 0); + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH2, 0); + kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH3, 0); + } + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf); if (ret < 0) { return ret; @@ -3735,6 +3777,10 @@ static int kvm_get_msrs(X86CPU *cpu) case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B: env->msr_rtit_addrs[index - MSR_IA32_RTIT_ADDR0_A] = msrs[i].data; break; + case MSR_IA32_SGXLEPUBKEYHASH0 ... MSR_IA32_SGXLEPUBKEYHASH3: + env->msr_ia32_sgxlepubkeyhash[index - MSR_IA32_SGXLEPUBKEYHASH0] = + msrs[i].data; + break; } } @@ -4617,6 +4663,35 @@ void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) } } +static bool has_sgx_provisioning; + +static bool __kvm_enable_sgx_provisioning(KVMState *s) +{ + int fd, ret; + + if (!kvm_vm_check_extension(s, KVM_CAP_SGX_ATTRIBUTE)) { + return false; + } + + fd = qemu_open_old("/dev/sgx_provision", O_RDONLY); + if (fd < 0) { + return false; + } + + ret = kvm_vm_enable_cap(s, KVM_CAP_SGX_ATTRIBUTE, 0, fd); + if (ret) { + error_report("Could not enable SGX PROVISIONKEY: %s", strerror(-ret)); + exit(1); + } + close(fd); + return true; +} + +bool kvm_enable_sgx_provisioning(KVMState *s) +{ + return MEMORIZE(__kvm_enable_sgx_provisioning(s), has_sgx_provisioning); +} + static bool host_supports_vmx(void) { uint32_t ecx, unused; diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index 54667b3..a978509 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -51,4 +51,6 @@ bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp); uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address); +bool kvm_enable_sgx_provisioning(KVMState *s); + #endif diff --git a/target/i386/machine.c b/target/i386/machine.c index b094311..4367931 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -1415,6 +1415,25 @@ static const VMStateDescription vmstate_msr_tsx_ctrl = { } }; +static bool intel_sgx_msrs_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return !!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_SGX_LC); +} + +static const VMStateDescription vmstate_msr_intel_sgx = { + .name = "cpu/intel_sgx", + .version_id = 1, + .minimum_version_id = 1, + .needed = intel_sgx_msrs_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64_ARRAY(env.msr_ia32_sgxlepubkeyhash, X86CPU, 4), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_x86_cpu = { .name = "cpu", .version_id = 12, @@ -1551,6 +1570,7 @@ const VMStateDescription vmstate_x86_cpu = { &vmstate_nested_state, #endif &vmstate_msr_tsx_ctrl, + &vmstate_msr_intel_sgx, NULL } }; diff --git a/target/i386/monitor.c b/target/i386/monitor.c index 119211f..196c1c9 100644 --- a/target/i386/monitor.c +++ b/target/i386/monitor.c @@ -35,6 +35,7 @@ #include "qapi/qapi-commands-misc-target.h" #include "qapi/qapi-commands-misc.h" #include "hw/i386/pc.h" +#include "hw/i386/sgx.h" /* Perform linear address sign extension */ static hwaddr addr_canonical(CPUArchState *env, hwaddr addr) @@ -763,3 +764,34 @@ qmp_query_sev_attestation_report(const char *mnonce, Error **errp) { return sev_get_attestation_report(mnonce, errp); } + +SGXInfo *qmp_query_sgx(Error **errp) +{ + return sgx_get_info(errp); +} + +void hmp_info_sgx(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + g_autoptr(SGXInfo) info = qmp_query_sgx(&err); + + if (err) { + error_report_err(err); + return; + } + monitor_printf(mon, "SGX support: %s\n", + info->sgx ? "enabled" : "disabled"); + monitor_printf(mon, "SGX1 support: %s\n", + info->sgx1 ? "enabled" : "disabled"); + monitor_printf(mon, "SGX2 support: %s\n", + info->sgx2 ? "enabled" : "disabled"); + monitor_printf(mon, "FLC support: %s\n", + info->flc ? "enabled" : "disabled"); + monitor_printf(mon, "size: %" PRIu64 "\n", + info->section_size); +} + +SGXInfo *qmp_query_sgx_capabilities(Error **errp) +{ + return sgx_get_capabilities(errp); +} diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c index a488b00..14c996f 100644 --- a/target/i386/nvmm/nvmm-all.c +++ b/target/i386/nvmm/nvmm-all.c @@ -1123,6 +1123,7 @@ nvmm_log_sync(MemoryListener *listener, MemoryRegionSection *section) } static MemoryListener nvmm_memory_listener = { + .name = "nvmm", .begin = nvmm_transaction_begin, .commit = nvmm_transaction_commit, .region_add = nvmm_region_add, diff --git a/target/i386/sev.c b/target/i386/sev.c index 0b2c8f5..fa72104 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -565,7 +565,7 @@ static int sev_read_file_base64(const char *filename, guchar **data, gsize *len) { gsize sz; - gchar *base64; + g_autofree gchar *base64 = NULL; GError *error = NULL; if (!g_file_get_contents(filename, &base64, &sz, &error)) { diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c index 3e925b9..ef896da 100644 --- a/target/i386/whpx/whpx-all.c +++ b/target/i386/whpx/whpx-all.c @@ -1598,6 +1598,7 @@ static void whpx_log_sync(MemoryListener *listener, } static MemoryListener whpx_memory_listener = { + .name = "whpx", .begin = whpx_transaction_begin, .commit = whpx_transaction_commit, .region_add = whpx_region_add, |