On Fri, Aug 25, 2023, Tom Lendacky wrote: > On 8/24/23 20:36, Sean Christopherson wrote: > > Treat EMULTYPE_SKIP failures on SEV guests as unhandleable emulation > > instead of simply resuming the guest, and drop the hack-a-fix which > > effects that behavior for the INT3/INTO injection path. If KVM can't > > skip an instruction for which KVM has already done partial emulation, > > resuming the guest is undesirable as doing so may corrupt guest state. > > > > Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> > > --- > > arch/x86/kvm/svm/svm.c | 12 +----------- > > arch/x86/kvm/x86.c | 9 +++++++-- > > 2 files changed, 8 insertions(+), 13 deletions(-) > > > > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c > > index 39ce680013c4..fc2cd5585349 100644 > > --- a/arch/x86/kvm/svm/svm.c > > +++ b/arch/x86/kvm/svm/svm.c > > @@ -364,8 +364,6 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) > > svm->vmcb->control.int_state |= SVM_INTERRUPT_SHADOW_MASK; > > } > > -static int svm_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, > > - void *insn, int insn_len); > > static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, > > bool commit_side_effects) > > @@ -386,14 +384,6 @@ static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, > > } > > if (!svm->next_rip) { > > - /* > > - * FIXME: Drop this when kvm_emulate_instruction() does the > > - * right thing and treats "can't emulate" as outright failure > > - * for EMULTYPE_SKIP. > > - */ > > - if (svm_check_emulate_instruction(vcpu, EMULTYPE_SKIP, NULL, 0) != X86EMUL_CONTINUE) > > - return 0; > > - > > if (unlikely(!commit_side_effects)) > > old_rflags = svm->vmcb->save.rflags; > > @@ -4752,7 +4742,7 @@ static int svm_check_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, > > */ > > if (unlikely(!insn)) { > > if (emul_type & EMULTYPE_SKIP) > > - return X86EMUL_RETRY_INSTR; > > + return X86EMUL_UNHANDLEABLE; > > Trying to follow this, bear with me... > > This results in an "emulation failure" which fills out all the KVM userspace > exit information in prepare_emulation_failure_exit(). But because of the > return 0 in handle_emulation_failure(), in the end this ends up just acting > like the first patch because we exit out svm_update_soft_interrupt_rip() > early and the instruction just gets retried? Yep. It's a bit more labyrinthian than I'd like, but the soft injection already relies on this behavior to handle the case where x86_decode_emulated_instruction() fails. That's a much more theoretical path, but I'm pretty sure if could trigger if the guest is replacing the INT3 from a different vCPU and KVM's emulator doesn't know how to decode the new instruction.