diff mbox

[02/15] xen: vmx: detect ENCLS VMEXIT

Message ID 4b8baf9779038897e6ba2ed4ac0a3e9663db2756.1499586046.git.kai.huang@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kai Huang July 9, 2017, 8:09 a.m. UTC
If ENCLS VMEXIT is not present then we cannot support SGX virtualization.
This patch detects presence of ENCLS VMEXIT. A Xen boot boolean parameter
'sgx' is also added to manually enable/disable SGX.

Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
---
 xen/arch/x86/hvm/vmx/vmcs.c        | 17 +++++++++++++++++
 xen/include/asm-x86/hvm/vmx/vmcs.h |  3 +++
 2 files changed, 20 insertions(+)

Comments

Andrew Cooper July 12, 2017, 11:11 a.m. UTC | #1
On 09/07/17 10:09, Kai Huang wrote:
> If ENCLS VMEXIT is not present then we cannot support SGX virtualization.
> This patch detects presence of ENCLS VMEXIT. A Xen boot boolean parameter
> 'sgx' is also added to manually enable/disable SGX.
>
> Signed-off-by: Kai Huang <kai.huang@linux.intel.com>

At a minimum, you also need to modify calculate_hvm_max_policy() to hide 
SGX if we don't have ENCLS intercept support.

~Andrew
Jan Beulich July 12, 2017, 6:54 p.m. UTC | #2
>>> Andrew Cooper <andrew.cooper3@citrix.com> 07/12/17 1:12 PM >>>
>On 09/07/17 10:09, Kai Huang wrote:
>> If ENCLS VMEXIT is not present then we cannot support SGX virtualization.
>> This patch detects presence of ENCLS VMEXIT. A Xen boot boolean parameter
>> 'sgx' is also added to manually enable/disable SGX.
>>
>> Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
>
>At a minimum, you also need to modify calculate_hvm_max_policy() to hide 
>SGX if we don't have ENCLS intercept support.

Additionally I think the command line option should default to off initially
and it needs an entry in the command line option doc.

Jan
Kai Huang July 13, 2017, 4:57 a.m. UTC | #3
On 7/13/2017 6:54 AM, Jan Beulich wrote:
>>>> Andrew Cooper <andrew.cooper3@citrix.com> 07/12/17 1:12 PM >>>
>> On 09/07/17 10:09, Kai Huang wrote:
>>> If ENCLS VMEXIT is not present then we cannot support SGX virtualization.
>>> This patch detects presence of ENCLS VMEXIT. A Xen boot boolean parameter
>>> 'sgx' is also added to manually enable/disable SGX.
>>>
>>> Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
>>
>> At a minimum, you also need to modify calculate_hvm_max_policy() to hide
>> SGX if we don't have ENCLS intercept support.

Actually IMO this is not needed, as I added an __initcall(sgx_init) (see 
patch 0003), where I will call setup_clear_cpu_cap(X86_FEATURE_SGX) if 
for any reason boot_sgx_cpuidata (which contains common SGX cpuid info 
shared by all cores) doesn't have valid SGX info. if ENCLS VMEXIT is not 
present, then detect_sgx won't be called for any core so that 
X86_FEATURE_SGX will be cleared in boot_cpu_data. As init_guest_cpuid is 
called after all __initcalls are called, so if ENCLS VMEXIT is not 
present, or sgx is disabled via boot parameter, then even for 
host_policy, it won't have SGX.

Of course if we changed the implementation of __initcall(sgx_init), we 
probably need to explicitly clear SGX here. Anyway clearing SGX here 
doesn't have any harm, so I am completely fine to do it if you think it 
is necessary.

> 
> Additionally I think the command line option should default to off initially
> and it needs an entry in the command line option doc.

Sure. I'll change default to 0 and change the doc as well.

Thanks,
-Kai
> 
> Jan
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel
>
diff mbox

Patch

diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index 8103b20d29..ae7e6f9321 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -98,6 +98,9 @@  static void __init parse_ept_param(char *s)
 }
 custom_param("ept", parse_ept_param);
 
+static bool_t __read_mostly opt_sgx_enabled = 1;
+boolean_param("sgx", opt_sgx_enabled);
+
 /* Dynamic (run-time adjusted) execution control flags. */
 u32 vmx_pin_based_exec_control __read_mostly;
 u32 vmx_cpu_based_exec_control __read_mostly;
@@ -138,6 +141,7 @@  static void __init vmx_display_features(void)
     P(cpu_has_vmx_virt_exceptions, "Virtualisation Exceptions");
     P(cpu_has_vmx_pml, "Page Modification Logging");
     P(cpu_has_vmx_tsc_scaling, "TSC Scaling");
+    P(cpu_has_vmx_encls, "SGX ENCLS Exiting");
 #undef P
 
     if ( !printed )
@@ -243,6 +247,8 @@  static int vmx_init_vmcs_config(void)
             opt |= SECONDARY_EXEC_UNRESTRICTED_GUEST;
         if ( opt_pml_enabled )
             opt |= SECONDARY_EXEC_ENABLE_PML;
+        if ( opt_sgx_enabled )
+            opt |= SECONDARY_EXEC_ENABLE_ENCLS;
 
         /*
          * "APIC Register Virtualization" and "Virtual Interrupt Delivery"
@@ -336,6 +342,14 @@  static int vmx_init_vmcs_config(void)
         _vmx_secondary_exec_control &= ~ SECONDARY_EXEC_PAUSE_LOOP_EXITING;
     }
 
+    /*
+     * Turn off SGX if ENCLS VMEXIT is not present. Actually on real machine,
+     * if SGX CPUID is present (CPUID.0x7.0x0:EBX.SGX = 1), then ENCLS VMEXIT
+     * will always be present. We do the check anyway here.
+     */
+    if ( !(_vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_ENCLS) )
+        opt_sgx_enabled = 0;
+
     min = VM_EXIT_ACK_INTR_ON_EXIT;
     opt = VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_LOAD_HOST_PAT |
           VM_EXIT_CLEAR_BNDCFGS;
@@ -1146,6 +1160,9 @@  static int construct_vmcs(struct vcpu *v)
     /* Disable PML anyway here as it will only be enabled in log dirty mode */
     v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
 
+    /* Disable ENCLS VMEXIT. It will only be turned on when needed. */
+    v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_ENCLS;
+
     /* Host data selectors. */
     __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
     __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index e3cdfdf576..889091da42 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -232,6 +232,7 @@  extern u32 vmx_vmentry_control;
 #define SECONDARY_EXEC_ENABLE_INVPCID           0x00001000
 #define SECONDARY_EXEC_ENABLE_VM_FUNCTIONS      0x00002000
 #define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING    0x00004000
+#define SECONDARY_EXEC_ENABLE_ENCLS             0x00008000
 #define SECONDARY_EXEC_ENABLE_PML               0x00020000
 #define SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS   0x00040000
 #define SECONDARY_EXEC_XSAVES                   0x00100000
@@ -312,6 +313,8 @@  extern u64 vmx_ept_vpid_cap;
     (vmx_secondary_exec_control & SECONDARY_EXEC_XSAVES)
 #define cpu_has_vmx_tsc_scaling \
     (vmx_secondary_exec_control & SECONDARY_EXEC_TSC_SCALING)
+#define cpu_has_vmx_encls \
+    (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_ENCLS)
 
 #define VMCS_RID_TYPE_MASK              0x80000000