diff mbox

[07/10] kvm: vmx: add SGX IA32_FEATURE_CONTROL MSR emulation

Message ID 20170508052434.3627-8-kai.huang@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kai Huang May 8, 2017, 5:24 a.m. UTC
If CPUID.0x7.0:EBX.SGX == 1, IA32_FEATURE_CONTROL bit 18 (SGX enable) is valid.
If CPUID.0x7.0:ECX[bit30] = 1, IA32_FEATURE_CONTROL bit 17 (SGX Launch Control)
is valid. This patch emulate the two new bits for IA32_FEATURE_CONTROL MSR.

Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
---
 arch/x86/include/asm/msr-index.h |  2 ++
 arch/x86/kvm/vmx.c               | 28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)
diff mbox

Patch

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index d8b5f8ab8ef9..e3770f570bb9 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -422,6 +422,8 @@ 
 #define FEATURE_CONTROL_LOCKED				(1<<0)
 #define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX	(1<<1)
 #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX	(1<<2)
+#define FEATURE_CONTROL_SGX_LAUNCH_CONTROL_ENABLE	(1<<17)
+#define FEATURE_CONTROL_SGX_ENABLE			(1<<18)
 #define FEATURE_CONTROL_LMCE				(1<<20)
 
 #define MSR_IA32_APICBASE		0x0000001b
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 3c1cc94e7e6d..a16539594a99 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3329,6 +3329,20 @@  static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		vmx->msr_ia32_feature_control = data;
 		if (msr_info->host_initiated && data == 0)
 			vmx_leave_nested(vcpu);
+		/*
+		 * If guest's FEATURE_CONTROL_SGX_ENABLE is disabled, shall
+		 * we also clear vcpu's SGX CPUID? SDM (chapter 37.7.7.1)
+		 * says FEATURE_CONTROL_SGX_ENABLE bit doesn't reflect SGX
+		 * CPUID but in reality seems if FEATURE_CONTROL_SGX_ENABLE
+		 * is disabled, SGX CPUID will reports (at least) invalid EPC.
+		 * But looks we cannot just simply clear vcpu's SGX CPUID,
+		 * as Qemu may write IA32_FEATURE_CONTROL *before* or *after*
+		 * KVM_SET_CPUID2. If KVM_SET_CPUID2 is called first, and we
+		 * clear vcpu's SGX CPUID here, we will not be able to enable
+		 * SGX again as SGX CPUID info has already lost. Therefore do
+		 * nothing here. We assume guest will always check whether
+		 * SGX has been enabled in BIOS before using SGX.
+		 */
 		break;
 	case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
 		if (!msr_info->host_initiated)
@@ -9594,6 +9608,20 @@  static int vmx_cpuid_update(struct kvm_vcpu *vcpu)
 	if (r)
 		return r;
 
+	if (guest_cpuid_has_sgx(vcpu)) {
+		/*
+		 * If CPUID.0x7.0:EBX.SGX = 1, SGX can be opt-in{out} in BIOS
+		 * via IA32_FEATURE_CONTROL bit 18. If CPUID.0x7.0:ECX[bit30]
+		 * = 1, IA32_FEATURE_CONTROL bit 17 is valid to enable runtime
+		 * SGX Launch Control.
+		 */
+		to_vmx(vcpu)->msr_ia32_feature_control_valid_bits |=
+			FEATURE_CONTROL_SGX_ENABLE;
+		if (guest_cpuid_has_sgx_launch_control(vcpu))
+			to_vmx(vcpu)->msr_ia32_feature_control_valid_bits |=
+				FEATURE_CONTROL_SGX_LAUNCH_CONTROL_ENABLE;
+	}
+
 	return 0;
 }