linux/arch/x86/kvm/vmx/sgx.c

51 lines
1.2 KiB
C
Raw Normal View History

// 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;
}