1*9798adbcSSean Christopherson // SPDX-License-Identifier: GPL-2.0 2*9798adbcSSean Christopherson /* Copyright(c) 2021 Intel Corporation. */ 3*9798adbcSSean Christopherson 4*9798adbcSSean Christopherson #include <asm/sgx.h> 5*9798adbcSSean Christopherson 6*9798adbcSSean Christopherson #include "cpuid.h" 7*9798adbcSSean Christopherson #include "kvm_cache_regs.h" 8*9798adbcSSean Christopherson #include "sgx.h" 9*9798adbcSSean Christopherson #include "vmx.h" 10*9798adbcSSean Christopherson #include "x86.h" 11*9798adbcSSean Christopherson 12*9798adbcSSean Christopherson bool __read_mostly enable_sgx; 13*9798adbcSSean Christopherson 14*9798adbcSSean Christopherson static inline bool encls_leaf_enabled_in_guest(struct kvm_vcpu *vcpu, u32 leaf) 15*9798adbcSSean Christopherson { 16*9798adbcSSean Christopherson if (!enable_sgx || !guest_cpuid_has(vcpu, X86_FEATURE_SGX)) 17*9798adbcSSean Christopherson return false; 18*9798adbcSSean Christopherson 19*9798adbcSSean Christopherson if (leaf >= ECREATE && leaf <= ETRACK) 20*9798adbcSSean Christopherson return guest_cpuid_has(vcpu, X86_FEATURE_SGX1); 21*9798adbcSSean Christopherson 22*9798adbcSSean Christopherson if (leaf >= EAUG && leaf <= EMODT) 23*9798adbcSSean Christopherson return guest_cpuid_has(vcpu, X86_FEATURE_SGX2); 24*9798adbcSSean Christopherson 25*9798adbcSSean Christopherson return false; 26*9798adbcSSean Christopherson } 27*9798adbcSSean Christopherson 28*9798adbcSSean Christopherson static inline bool sgx_enabled_in_guest_bios(struct kvm_vcpu *vcpu) 29*9798adbcSSean Christopherson { 30*9798adbcSSean Christopherson const u64 bits = FEAT_CTL_SGX_ENABLED | FEAT_CTL_LOCKED; 31*9798adbcSSean Christopherson 32*9798adbcSSean Christopherson return (to_vmx(vcpu)->msr_ia32_feature_control & bits) == bits; 33*9798adbcSSean Christopherson } 34*9798adbcSSean Christopherson 35*9798adbcSSean Christopherson int handle_encls(struct kvm_vcpu *vcpu) 36*9798adbcSSean Christopherson { 37*9798adbcSSean Christopherson u32 leaf = (u32)kvm_rax_read(vcpu); 38*9798adbcSSean Christopherson 39*9798adbcSSean Christopherson if (!encls_leaf_enabled_in_guest(vcpu, leaf)) { 40*9798adbcSSean Christopherson kvm_queue_exception(vcpu, UD_VECTOR); 41*9798adbcSSean Christopherson } else if (!sgx_enabled_in_guest_bios(vcpu)) { 42*9798adbcSSean Christopherson kvm_inject_gp(vcpu, 0); 43*9798adbcSSean Christopherson } else { 44*9798adbcSSean Christopherson WARN(1, "KVM: unexpected exit on ENCLS[%u]", leaf); 45*9798adbcSSean Christopherson vcpu->run->exit_reason = KVM_EXIT_UNKNOWN; 46*9798adbcSSean Christopherson vcpu->run->hw.hardware_exit_reason = EXIT_REASON_ENCLS; 47*9798adbcSSean Christopherson return 0; 48*9798adbcSSean Christopherson } 49*9798adbcSSean Christopherson return 1; 50*9798adbcSSean Christopherson } 51