mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
51 lines
1.2 KiB
C
51 lines
1.2 KiB
C
![]() |
// SPDX-License-Identifier: GPL-2.0
|
||
|
/* Copyright(c) 2021 Intel Corporation. */
|
||
|
|
||
|
#include <asm/sgx.h>
|
||
|
|
||
|
#include "cpuid.h"
|
||
|
#include "kvm_cache_regs.h"
|
||
|
#include "sgx.h"
|
||
|
#include "vmx.h"
|
||
|
#include "x86.h"
|
||
|
|
||
|
bool __read_mostly enable_sgx;
|
||
|
|
||
|
static inline bool encls_leaf_enabled_in_guest(struct kvm_vcpu *vcpu, u32 leaf)
|
||
|
{
|
||
|
if (!enable_sgx || !guest_cpuid_has(vcpu, X86_FEATURE_SGX))
|
||
|
return false;
|
||
|
|
||
|
if (leaf >= ECREATE && leaf <= ETRACK)
|
||
|
return guest_cpuid_has(vcpu, X86_FEATURE_SGX1);
|
||
|
|
||
|
if (leaf >= EAUG && leaf <= EMODT)
|
||
|
return guest_cpuid_has(vcpu, X86_FEATURE_SGX2);
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static inline bool sgx_enabled_in_guest_bios(struct kvm_vcpu *vcpu)
|
||
|
{
|
||
|
const u64 bits = FEAT_CTL_SGX_ENABLED | FEAT_CTL_LOCKED;
|
||
|
|
||
|
return (to_vmx(vcpu)->msr_ia32_feature_control & bits) == bits;
|
||
|
}
|
||
|
|
||
|
int handle_encls(struct kvm_vcpu *vcpu)
|
||
|
{
|
||
|
u32 leaf = (u32)kvm_rax_read(vcpu);
|
||
|
|
||
|
if (!encls_leaf_enabled_in_guest(vcpu, leaf)) {
|
||
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
||
|
} else if (!sgx_enabled_in_guest_bios(vcpu)) {
|
||
|
kvm_inject_gp(vcpu, 0);
|
||
|
} else {
|
||
|
WARN(1, "KVM: unexpected exit on ENCLS[%u]", leaf);
|
||
|
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
|
||
|
vcpu->run->hw.hardware_exit_reason = EXIT_REASON_ENCLS;
|
||
|
return 0;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|