[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 11/15] xen: vmx: handle VMEXIT from SGX enclave
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.huang@xxxxxxxxxxxxxxx> --- 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 ea3d468bb0..d0c43ea0c8 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -57,6 +57,7 @@ #include <asm/event.h> #include <asm/monitor.h> #include <public/arch-x86/cpuid.h> +#include <asm/hvm/vmx/sgx.h> static bool_t __initdata opt_force_ept; boolean_param("force-ept", opt_force_ept); @@ -3544,6 +3545,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); @@ -3569,6 +3571,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 ) { @@ -4070,6 +4077,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 */ @@ -4081,6 +4100,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 1350b7bc81..bbbc3d0d78 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -327,6 +327,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 211f5c8058..2184d35246 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -153,6 +153,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.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |