Re: [PATCH v2 6/7] KVM:VMX: Load Guest CET via VMCS when CET is enabled in Guest

From: Yang Weijiang
Date: Thu Jan 31 2019 - 03:23:06 EST


On Fri, Jan 25, 2019 at 02:56:25PM -0800, Sean Christopherson wrote:
> On Wed, Jan 23, 2019 at 04:59:08AM +0800, Yang Weijiang wrote:
> > "Load Guest CET state" bit controls whether guest CET states
> > will be loaded on Guest entry. Before doing that, KVM needs
> > to check if CET feature is exposed to Guest.
> >
> > Signed-off-by: Zhang Yi Z <yi.z.zhang@xxxxxxxxxxxxxxx>
> > Signed-off-by: Yang Weijiang <weijiang.yang@xxxxxxxxx>
> > ---
> > arch/x86/kvm/vmx.c | 33 +++++++++++++++++++++++++++++++++
> > 1 file changed, 33 insertions(+)
> >
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index 68c0e5e41cb1..9c8cecac80ea 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -55,6 +55,7 @@
> > #include <asm/mmu_context.h>
> > #include <asm/spec-ctrl.h>
> > #include <asm/mshyperv.h>
> > +#include <asm/cet.h>
> >
> > #include "trace.h"
> > #include "pmu.h"
> > @@ -4065,6 +4066,18 @@ static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu,
> > return !(val & ~valid_bits);
> > }
> >
> > +static int vmx_guest_cet_cap(struct kvm_vcpu *vcpu)
> > +{
> > + struct kvm_cpuid_entry2 *best;
> > + int r = 0;
> > +
> > + best = kvm_find_cpuid_entry(vcpu, 7, 0);
> > + if (best && best->function == 0x7)
> > + r = (best->ecx & bit(X86_FEATURE_SHSTK)) |
> > + (best->edx & bit(X86_FEATURE_IBT)) ? 1 : 0;
> > + return r;
> > +}
> > +
> > static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
> > {
> > switch (msr->index) {
> > @@ -5409,6 +5422,26 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
> > return 1;
> > }
> >
> > + /*
> > + * To enable Guest CET, first check if Guest CET feature is
> > + * available, if it's not available but its CR4.CET is being set,
> > + * return a fault to Guest; then check if Host CET is enabled and
> > + * CR4.CET is toggled, if they are, then enable loading CET state
>
> Comment doesn't match the code. Comment says "toggled", code is just
> looking at "enabled".
>
> > + * bit in entry control, otherwise, clear the bit to
> > + * disable guest CET state loading.
>
> What happens to CET state if the control is clear? Is host state
> retained but inaccessible?
>
Hi, Sean,
I consulted the CET arch for the feature enabling in guest, actually, it
can be enabled independent to host CET feature, i.e., guest CET feature
can work even without host CET feature off, I did experiments, it's
proved true. So, in next version, I'll remove host CET dependencies to
make the KVM code look much cleaner. Thanks for your comments.

> > + */
> > + if (vmx_guest_cet_cap(vcpu)) {
>
> Why not?
>
> if (guest_cpuid_has(vcpu, X86_FEATURE_SHSTK) ||
> guest_cpuid_has(vcpu, X86_FEATURE_IBT)) {
>
> > + if (hw_cr4 & cr4 & X86_CR4_CET) {
> > + vmcs_set_bits(VM_ENTRY_CONTROLS,
> > + VM_ENTRY_LOAD_GUEST_CET_STATE);
> > + } else {
> > + vmcs_clear_bits(VM_ENTRY_CONTROLS,
> > + VM_ENTRY_LOAD_GUEST_CET_STATE);
> > + }
> > + } else if (cr4 & X86_CR4_CET) {
> > + return 1;
> > + }
> > +
> > if (to_vmx(vcpu)->nested.vmxon && !nested_cr4_valid(vcpu, cr4))
> > return 1;
> >
> > --
> > 2.17.1
> >