On Thu, Feb 04, 2021, Paolo Bonzini wrote: > On 03/02/21 22:46, Sean Christopherson wrote: > > > > diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c > > index dbca1687ae8e..0b6dab6915a3 100644 > > --- a/arch/x86/kvm/vmx/nested.c > > +++ b/arch/x86/kvm/vmx/nested.c > > @@ -2811,7 +2811,7 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu, > > /* VM-entry interruption-info field: deliver error code */ > > should_have_error_code = > > intr_type == INTR_TYPE_HARD_EXCEPTION && prot_mode && > > - x86_exception_has_error_code(vector); > > + x86_exception_has_error_code(vcpu, vector); > > if (CC(has_error_code != should_have_error_code)) > > return -EINVAL; > > > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > > index 28fea7ff7a86..0288d6a364bd 100644 > > --- a/arch/x86/kvm/x86.c > > +++ b/arch/x86/kvm/x86.c > > @@ -437,17 +437,20 @@ EXPORT_SYMBOL_GPL(kvm_spurious_fault); > > #define EXCPT_CONTRIBUTORY 1 > > #define EXCPT_PF 2 > > > > -static int exception_class(int vector) > > +static int exception_class(struct kvm_vcpu *vcpu, int vector) > > { > > switch (vector) { > > case PF_VECTOR: > > return EXCPT_PF; > > + case CP_VECTOR: > > + if (vcpu->arch.cr4_guest_rsvd_bits & X86_CR4_CET) > > + return EXCPT_BENIGN; > > + return EXCPT_CONTRIBUTORY; > > case DE_VECTOR: > > case TS_VECTOR: > > case NP_VECTOR: > > case SS_VECTOR: > > case GP_VECTOR: > > - case CP_VECTOR: This removal got lost when squasing. arch/x86/kvm/x86.c: In function ‘exception_class’: arch/x86/kvm/x86.c:455:2: error: duplicate case value 455 | case CP_VECTOR: | ^~~~ arch/x86/kvm/x86.c:446:2: note: previously used here 446 | case CP_VECTOR: | ^~~~ > > return EXCPT_CONTRIBUTORY; > > default: > > break; > > @@ -588,8 +591,8 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, > > kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); > > return; > > } > > - class1 = exception_class(prev_nr); > > - class2 = exception_class(nr); > > + class1 = exception_class(vcpu, prev_nr); > > + class2 = exception_class(vcpu, nr); > > if ((class1 == EXCPT_CONTRIBUTORY && class2 == EXCPT_CONTRIBUTORY) > > || (class1 == EXCPT_PF && class2 != EXCPT_BENIGN)) { > > /* > > diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h > > index a14da36a30ed..dce756ffb577 100644 > > --- a/arch/x86/kvm/x86.h > > +++ b/arch/x86/kvm/x86.h > > @@ -120,12 +120,16 @@ static inline bool is_la57_mode(struct kvm_vcpu *vcpu) > > #endif > > } > > > > -static inline bool x86_exception_has_error_code(unsigned int vector) > > +static inline bool x86_exception_has_error_code(struct kvm_vcpu *vcpu, > > + unsigned int vector) > > { > > static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) | > > BIT(NP_VECTOR) | BIT(SS_VECTOR) | BIT(GP_VECTOR) | > > BIT(PF_VECTOR) | BIT(AC_VECTOR) | BIT(CP_VECTOR); > > > > + if (vector == CP_VECTOR && (vcpu->arch.cr4_guest_rsvd_bits & X86_CR4_CET)) > > + return false; > > + > > return (1U << vector) & exception_has_error_code; > > } > > > > > > > > > > Squashed, thanks. I made a small change to the last hunk: > > if (!((1U << vector) & exception_has_error_code)) > return false; > > if (vector == CP_VECTOR) > return !(vcpu->arch.cr4_guest_rsvd_bits & X86_CR4_CET); > > return true; Ha, I guessed wrong, that was my first pass at it :-)