On 10/04/20 06:39, Xiaoyao Li wrote: > > +static bool guest_handles_ac(struct kvm_vcpu *vcpu) > +{ > + /* > + * If guest has alignment checking enabled in CR0 and activated in > + * eflags, then the #AC originated from CPL3 and the guest is able > + * to handle it. It does not matter whether this is a regular or > + * a split lock operation induced #AC. > + */ > + if (vmx_get_cpl(vcpu) == 3 && kvm_read_cr0_bits(vcpu, X86_CR0_AM) && > + kvm_get_rflags(vcpu) & X86_EFLAGS_AC) > + return true; > + > + /* Add guest SLD handling checks here once it's supported */ > + return false; > +} > + > static int handle_exception_nmi(struct kvm_vcpu *vcpu) > { > struct vcpu_vmx *vmx = to_vmx(vcpu); > @@ -4630,6 +4647,7 @@ static int handle_exception_nmi(struct k > u32 intr_info, ex_no, error_code; > unsigned long cr2, rip, dr6; > u32 vect_info; > + int err; > vect_info = vmx->idt_vectoring_info; > intr_info = vmx->exit_intr_info; > @@ -4688,9 +4706,6 @@ static int handle_exception_nmi(struct k > return handle_rmode_exception(vcpu, ex_no, error_code); > switch (ex_no) { > - case AC_VECTOR: > - kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); > - return 1; > case DB_VECTOR: > dr6 = vmcs_readl(EXIT_QUALIFICATION); > if (!(vcpu->guest_debug & > @@ -4719,6 +4734,29 @@ static int handle_exception_nmi(struct k > kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip; > kvm_run->debug.arch.exception = ex_no; > break; > + case AC_VECTOR: > + if (guest_handles_ac(vcpu)) { > + kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); > + return 1; > + } > + /* > + * Handle #AC caused by split lock detection. If the host > + * mode is sld_warn, then it warns, marks current with > + * TIF_SLD and disables split lock detection. So the guest > + * can just continue. > + * > + * If the host mode is fatal, the handling code warned. Let > + * qemu kill itself. > + * > + * If the host mode is off, then this #AC is bonkers and > + * something is badly wrong. Let it fail as well. > + */ > + err = handle_ac_split_lock(kvm_rip_read(vcpu)); > + if (!err) > + return 1; > + /* Propagate the error type to user space */ > + error_code = err == -EFAULT ? 0x100 : 0x200; > + fallthrough; Acked-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>