xref: /openbmc/linux/arch/x86/kvm/vmx/sgx.c (revision 9798adbc)
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