From 1724996bc597b085f1b2101e5e9fc2b9929197b4 Mon Sep 17 00:00:00 2001 From: Binbin Wu Date: Wed, 22 May 2019 15:30:05 +0800 Subject: [PATCH] hv: vcpuid: present sgx capabilities to guest If sgx is supported in guest, present SGX capabilities to guest. There will be only one EPC section presented to guest, even if EPC memory for a guest is from muiltiple physcial EPC sections. Tracked-On: #3179 Signed-off-by: Binbin Wu Reviewed-by: Yan, Like Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vcpuid.c | 108 +++++++++++++++++++++------- hypervisor/include/arch/x86/cpuid.h | 10 ++- 2 files changed, 89 insertions(+), 29 deletions(-) diff --git a/hypervisor/arch/x86/guest/vcpuid.c b/hypervisor/arch/x86/guest/vcpuid.c index 7355fba14..1abcea936 100644 --- a/hypervisor/arch/x86/guest/vcpuid.c +++ b/hypervisor/arch/x86/guest/vcpuid.c @@ -12,6 +12,7 @@ #include #include #include +#include #include static inline const struct vcpuid_entry *local_find_vcpuid_entry(const struct acrn_vcpu *vcpu, @@ -193,6 +194,80 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, } } +static int32_t set_vcpuid_sgx(struct acrn_vm *vm) +{ + int32_t result = 0; + + if (is_vsgx_supported(vm->vm_id)) { + struct vcpuid_entry entry; + struct epc_map* maps; + uint32_t mid; + uint64_t size = 0; + /* init cpuid.12h.0h */ + init_vcpuid_entry(CPUID_SGX_LEAF, 0U, CPUID_CHECK_SUBLEAF, &entry); + result = set_vcpuid_entry(vm, &entry); + /* init cpuid.12h.1h */ + if (result == 0) { + init_vcpuid_entry(CPUID_SGX_LEAF, 1U, CPUID_CHECK_SUBLEAF, &entry); + /* MPX not present to guest */ + entry.ecx &= ~XCR0_BNDREGS; + entry.ecx &= ~XCR0_BNDCSR; + result = set_vcpuid_entry(vm, &entry); + } + if (result == 0) { + maps = get_epc_mapping(vm->vm_id); + /* init cpuid.12h.2h, only build one EPC section for a VM */ + for (mid = 0U; mid <= MAX_EPC_SECTIONS; mid++) { + size += maps[mid].size; + } + entry.leaf = CPUID_SGX_LEAF; + entry.subleaf = CPUID_SGX_EPC_SUBLEAF_BASE; + entry.flags = CPUID_CHECK_SUBLEAF; + entry.eax = CPUID_SGX_EPC_TYPE_VALID; + entry.eax |= (uint32_t)maps[0].gpa & CPUID_SGX_EPC_LOW_MASK; + entry.ebx = (uint32_t)(maps[0].gpa >> 32U) & CPUID_SGX_EPC_HIGH_MASK; + entry.ecx = (uint32_t)size & CPUID_SGX_EPC_LOW_MASK; + entry.edx = (uint32_t)(size >> 32U) & CPUID_SGX_EPC_HIGH_MASK; + result = set_vcpuid_entry(vm, &entry); + } + } + + return result; +} + +static int32_t set_vcpuid_extended_function(struct acrn_vm *vm) +{ + uint32_t i, limit; + struct vcpuid_entry entry; + int32_t result; + + init_vcpuid_entry(0x40000000U, 0U, 0U, &entry); + result = set_vcpuid_entry(vm, &entry); + if (result == 0) { + init_vcpuid_entry(0x40000010U, 0U, 0U, &entry); + result = set_vcpuid_entry(vm, &entry); + } + + if (result == 0) { + init_vcpuid_entry(0x80000000U, 0U, 0U, &entry); + result = set_vcpuid_entry(vm, &entry); + } + + if (result == 0) { + limit = entry.eax; + vm->vcpuid_xlevel = limit; + for (i = 0x80000002U; i <= limit; i++) { + init_vcpuid_entry(i, 0U, 0U, &entry); + result = set_vcpuid_entry(vm, &entry); + if (result != 0) { + break; + } + } + } + + return result; +} + int32_t set_vcpuid_entries(struct acrn_vm *vm) { int32_t result; @@ -237,17 +312,20 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm) pr_warn("vcpuid: only support subleaf 0 for cpu leaf 07h"); entry.eax = 0U; } + if (is_vsgx_supported(vm->vm_id)) { + entry.ebx |= CPUID_EBX_SGX; + } result = set_vcpuid_entry(vm, &entry); break; - + case 0x12U: + result = set_vcpuid_sgx(vm); + break; /* These features are disabled */ /* PMU is not supported */ case 0x0aU: /* Intel RDT */ case 0x0fU: case 0x10U: - /* Intel SGX */ - case 0x12U: /* Intel Processor Trace */ case 0x14U: break; @@ -265,29 +343,7 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm) } if (result == 0) { - init_vcpuid_entry(0x40000000U, 0U, 0U, &entry); - result = set_vcpuid_entry(vm, &entry); - if (result == 0) { - init_vcpuid_entry(0x40000010U, 0U, 0U, &entry); - result = set_vcpuid_entry(vm, &entry); - } - - if (result == 0) { - init_vcpuid_entry(0x80000000U, 0U, 0U, &entry); - result = set_vcpuid_entry(vm, &entry); - } - - if (result == 0) { - limit = entry.eax; - vm->vcpuid_xlevel = limit; - for (i = 0x80000002U; i <= limit; i++) { - init_vcpuid_entry(i, 0U, 0U, &entry); - result = set_vcpuid_entry(vm, &entry); - if (result != 0) { - break; - } - } - } + result = set_vcpuid_extended_function(vm); } } diff --git a/hypervisor/include/arch/x86/cpuid.h b/hypervisor/include/arch/x86/cpuid.h index 63e083756..eb4489140 100644 --- a/hypervisor/include/arch/x86/cpuid.h +++ b/hypervisor/include/arch/x86/cpuid.h @@ -97,11 +97,15 @@ /* CPUID.01H:ECX.PCID*/ #define CPUID_ECX_PCID (1U<<17U) /* CPUID.0DH.EAX.XCR0_BNDREGS */ -#define CPUID_EAX_XCR0_BNDREGS (1U<<3U) +#define CPUID_EAX_XCR0_BNDREGS (1U<<3U) /* CPUID.0DH.EAX.XCR0_BNDCSR */ -#define CPUID_EAX_XCR0_BNDCSR (1U<<4U) +#define CPUID_EAX_XCR0_BNDCSR (1U<<4U) +/* CPUID.12H.EAX.SGX1 */ +#define CPUID_EAX_SGX1 (1U<<0U) +/* CPUID.12H.EAX.SGX2 */ +#define CPUID_EAX_SGX2 (1U<<1U) /* CPUID.80000001H.EDX.XD_BIT_AVAILABLE */ -#define CPUID_EDX_XD_BIT_AVIL (1U<<20U) +#define CPUID_EDX_XD_BIT_AVIL (1U<<20U) /* CPUID source operands */ #define CPUID_VENDORSTRING 0U