Message ID | 4be4b49f63a6c66911683d0f093ca5ef0d3996d5.1617825858.git.kai.huang@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM SGX virtualization support (KVM part) | expand |
On Thu, Apr 08, 2021, Kai Huang wrote: > +int handle_encls(struct kvm_vcpu *vcpu) > +{ > + u32 leaf = (u32)vcpu->arch.regs[VCPU_REGS_RAX]; Please use kvm_rax_read(), I've been trying to discourage direct access to the array. Which is ironic because I'm 100% certain I'm to blame for this. :-) > + > + 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; > +}
On Wed, 7 Apr 2021 22:16:59 +0000 Sean Christopherson wrote: > On Thu, Apr 08, 2021, Kai Huang wrote: > > +int handle_encls(struct kvm_vcpu *vcpu) > > +{ > > + u32 leaf = (u32)vcpu->arch.regs[VCPU_REGS_RAX]; > > Please use kvm_rax_read(), I've been trying to discourage direct access to the > array. Which is ironic because I'm 100% certain I'm to blame for this. :-) Sure. But I think still, we should convert it to (u32) explicitly, so: 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; > > +}
On Thu, Apr 08, 2021, Kai Huang wrote: > On Wed, 7 Apr 2021 22:16:59 +0000 Sean Christopherson wrote: > > On Thu, Apr 08, 2021, Kai Huang wrote: > > > +int handle_encls(struct kvm_vcpu *vcpu) > > > +{ > > > + u32 leaf = (u32)vcpu->arch.regs[VCPU_REGS_RAX]; > > > > Please use kvm_rax_read(), I've been trying to discourage direct access to the > > array. Which is ironic because I'm 100% certain I'm to blame for this. :-) > > Sure. But I think still, we should convert it to (u32) explicitly, so: > > u32 leaf = (u32)kvm_rax_read(vcpu); > > ? Ya, agreed, it helps document that it's deliberate.
On Wed, 7 Apr 2021 22:35:32 +0000 Sean Christopherson wrote: > On Thu, Apr 08, 2021, Kai Huang wrote: > > On Wed, 7 Apr 2021 22:16:59 +0000 Sean Christopherson wrote: > > > On Thu, Apr 08, 2021, Kai Huang wrote: > > > > +int handle_encls(struct kvm_vcpu *vcpu) > > > > +{ > > > > + u32 leaf = (u32)vcpu->arch.regs[VCPU_REGS_RAX]; > > > > > > Please use kvm_rax_read(), I've been trying to discourage direct access to the > > > array. Which is ironic because I'm 100% certain I'm to blame for this. :-) > > > > Sure. But I think still, we should convert it to (u32) explicitly, so: > > > > u32 leaf = (u32)kvm_rax_read(vcpu); > > > > ? > > Ya, agreed, it helps document that it's deliberate. Do you have any other comments regarding to other patches? If no I can send another version rather quickly :)
On Thu, Apr 08, 2021, Kai Huang wrote: > On Wed, 7 Apr 2021 22:35:32 +0000 Sean Christopherson wrote: > > On Thu, Apr 08, 2021, Kai Huang wrote: > > > On Wed, 7 Apr 2021 22:16:59 +0000 Sean Christopherson wrote: > > > > On Thu, Apr 08, 2021, Kai Huang wrote: > > > > > +int handle_encls(struct kvm_vcpu *vcpu) > > > > > +{ > > > > > + u32 leaf = (u32)vcpu->arch.regs[VCPU_REGS_RAX]; > > > > > > > > Please use kvm_rax_read(), I've been trying to discourage direct access to the > > > > array. Which is ironic because I'm 100% certain I'm to blame for this. :-) > > > > > > Sure. But I think still, we should convert it to (u32) explicitly, so: > > > > > > u32 leaf = (u32)kvm_rax_read(vcpu); > > > > > > ? > > > > Ya, agreed, it helps document that it's deliberate. > > Do you have any other comments regarding to other patches? If no I can send > another version rather quickly :) Nope, nothing at this time. Though I'd give folks a few days to review before sending the next version, I don't think any of my feedback will affect other reviews.
On Wed, 7 Apr 2021 22:47:07 +0000 Sean Christopherson wrote: > On Thu, Apr 08, 2021, Kai Huang wrote: > > On Wed, 7 Apr 2021 22:35:32 +0000 Sean Christopherson wrote: > > > On Thu, Apr 08, 2021, Kai Huang wrote: > > > > On Wed, 7 Apr 2021 22:16:59 +0000 Sean Christopherson wrote: > > > > > On Thu, Apr 08, 2021, Kai Huang wrote: > > > > > > +int handle_encls(struct kvm_vcpu *vcpu) > > > > > > +{ > > > > > > + u32 leaf = (u32)vcpu->arch.regs[VCPU_REGS_RAX]; > > > > > > > > > > Please use kvm_rax_read(), I've been trying to discourage direct access to the > > > > > array. Which is ironic because I'm 100% certain I'm to blame for this. :-) > > > > > > > > Sure. But I think still, we should convert it to (u32) explicitly, so: > > > > > > > > u32 leaf = (u32)kvm_rax_read(vcpu); > > > > > > > > ? > > > > > > Ya, agreed, it helps document that it's deliberate. > > > > Do you have any other comments regarding to other patches? If no I can send > > another version rather quickly :) > > Nope, nothing at this time. Though I'd give folks a few days to review before > sending the next version, I don't think any of my feedback will affect other > reviews. My thinking too, but OK I'll wait for other people's review, plus I'd like to hear about on how to proceed given the current series has some merge conflicts with latest kvm/queue, although they are quite straightforward to resolve.
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 1b4766fe1de2..87f514c36eae 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -23,6 +23,8 @@ kvm-$(CONFIG_KVM_XEN) += xen.o kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \ vmx/evmcs.o vmx/nested.o vmx/posted_intr.o +kvm-intel-$(CONFIG_X86_SGX_KVM) += vmx/sgx.o + kvm-amd-y += svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o svm/sev.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/x86/kvm/vmx/sgx.c b/arch/x86/kvm/vmx/sgx.c new file mode 100644 index 000000000000..f68adbe38750 --- /dev/null +++ b/arch/x86/kvm/vmx/sgx.c @@ -0,0 +1,50 @@ +// 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)vcpu->arch.regs[VCPU_REGS_RAX]; + + 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; +} diff --git a/arch/x86/kvm/vmx/sgx.h b/arch/x86/kvm/vmx/sgx.h new file mode 100644 index 000000000000..6e17ecd4aca3 --- /dev/null +++ b/arch/x86/kvm/vmx/sgx.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __KVM_X86_SGX_H +#define __KVM_X86_SGX_H + +#include <linux/kvm_host.h> + +#ifdef CONFIG_X86_SGX_KVM +extern bool __read_mostly enable_sgx; + +int handle_encls(struct kvm_vcpu *vcpu); +#else +#define enable_sgx 0 +#endif + +#endif /* __KVM_X86_SGX_H */ diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 9dd185a53a3e..ef668047a8f9 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -57,6 +57,7 @@ #include "mmu.h" #include "nested.h" #include "pmu.h" +#include "sgx.h" #include "trace.h" #include "vmcs.h" #include "vmcs12.h" @@ -5673,16 +5674,18 @@ static int handle_vmx_instruction(struct kvm_vcpu *vcpu) return 1; } +#ifndef CONFIG_X86_SGX_KVM static int handle_encls(struct kvm_vcpu *vcpu) { /* - * SGX virtualization is not yet supported. There is no software - * enable bit for SGX, so we have to trap ENCLS and inject a #UD - * to prevent the guest from executing ENCLS. + * SGX virtualization is disabled. There is no software enable bit for + * SGX, so KVM intercepts all ENCLS leafs and injects a #UD to prevent + * the guest from executing ENCLS (when SGX is supported by hardware). */ kvm_queue_exception(vcpu, UD_VECTOR); return 1; } +#endif /* CONFIG_X86_SGX_KVM */ static int handle_bus_lock_vmexit(struct kvm_vcpu *vcpu) {