From: Kai Huang <kai.hu...@linux.intel.com> VMX adds new bit to both exit_reason and GUEST_INTERRUPT_STATE to indicate whether VMEXIT happens in Enclave. Several instructions are also invalid or behave differently in enclave according to SDM. This patch handles those cases.
Signed-off-by: Kai Huang <kai.hu...@linux.intel.com> --- xen/arch/x86/hvm/vmx/vmx.c | 29 +++++++++++++++++++++++++++++ xen/include/asm-x86/hvm/vmx/vmcs.h | 2 ++ xen/include/asm-x86/hvm/vmx/vmx.h | 2 ++ 3 files changed, 33 insertions(+) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index c48c44565fc5..280fc82ca1ff 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -58,6 +58,7 @@ #include <asm/mce.h> #include <asm/monitor.h> #include <public/arch-x86/cpuid.h> +#include <asm/sgx.h> static bool_t __initdata opt_force_ept; boolean_param("force-ept", opt_force_ept); @@ -3536,6 +3537,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) unsigned long exit_qualification, exit_reason, idtv_info, intr_info = 0; unsigned int vector = 0, mode; struct vcpu *v = current; + bool_t exit_from_sgx_enclave; __vmread(GUEST_RIP, ®s->rip); __vmread(GUEST_RSP, ®s->rsp); @@ -3561,6 +3563,11 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) perfc_incra(vmexits, exit_reason); + /* We need to handle several VMEXITs if VMEXIT is from enclave. Also clear + * bit 27 as it is further useless. */ + exit_from_sgx_enclave = !!(exit_reason & VMX_EXIT_REASONS_FROM_ENCLAVE); + exit_reason &= ~VMX_EXIT_REASONS_FROM_ENCLAVE; + /* Handle the interrupt we missed before allowing any more in. */ switch ( (uint16_t)exit_reason ) { @@ -4062,6 +4069,18 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) break; case EXIT_REASON_INVD: + /* + * SDM 39.6.5 INVD Handling when Enclave Are Enabled + * + * INVD cause #GP if EPC is enabled. + * FIXME: WBINVD?? + */ + if ( exit_from_sgx_enclave ) + { + hvm_inject_hw_exception(TRAP_gp_fault, 0); + break; + } + /* Otherwise passthrough */ case EXIT_REASON_WBINVD: { update_guest_eip(); /* Safe: INVD, WBINVD */ @@ -4073,6 +4092,16 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) { paddr_t gpa; + /* + * Currently EPT violation from enclave is not possible as all EPC pages + * are statically allocated to guest when guest is created. We simply + * crash guest in this case. + */ + if ( exit_from_sgx_enclave ) + { + domain_crash(v->domain); + break; + } __vmread(GUEST_PHYSICAL_ADDRESS, &gpa); __vmread(EXIT_QUALIFICATION, &exit_qualification); ept_handle_violation(exit_qualification, gpa); diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index f68f3d0f6801..52f137437b97 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -338,6 +338,8 @@ extern u64 vmx_ept_vpid_cap; #define VMX_INTR_SHADOW_MOV_SS 0x00000002 #define VMX_INTR_SHADOW_SMI 0x00000004 #define VMX_INTR_SHADOW_NMI 0x00000008 +#define VMX_INTR_ENCLAVE_INTR 0x00000010 /* VMEXIT was incident to + enclave mode */ #define VMX_BASIC_REVISION_MASK 0x7fffffff #define VMX_BASIC_VMCS_SIZE_MASK (0x1fffULL << 32) diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index 8547de9168eb..88d0dd600500 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -158,6 +158,8 @@ static inline void pi_clear_sn(struct pi_desc *pi_desc) * Exit Reasons */ #define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000 +/* Bit 27 is also set if VMEXIT is from SGX enclave mode */ +#define VMX_EXIT_REASONS_FROM_ENCLAVE 0x08000000 #define EXIT_REASON_EXCEPTION_NMI 0 #define EXIT_REASON_EXTERNAL_INTERRUPT 1 -- 2.15.0 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel