From: Mihai DONTU <mdontu@xxxxxxxxxxxxxxx> A previous patch has introduced support for single-stepping a guest (currently only VMX is supported). This mechanism is used to cope with instructions that cannot be handled by the x86 emulator during the handling of a VMEXIT. In these situations, all other vCPU-s are kicked and held, the EPT-based protection is removed and the guest is single stepped by the vCPU that triggered the initial VMEXIT. Upon completion the EPT-base protection is reinstalled and all vCPU-s all allowed to return to the guest. This is a rather slow workaround that kicks in occasionally. In the future, the most frequently single-stepped instructions should be added to the emulator (usually, stores to and from memory - SSE/AVX). This patch adds the VMX-side of events meant to disable the single step mechanism. Signed-off-by: Nicușor Cîțu <ncitu@xxxxxxxxxxxxxxx> Signed-off-by: Mihai Donțu <mdontu@xxxxxxxxxxxxxxx> --- arch/x86/kvm/vmx.c | 6 ++++++ arch/x86/kvm/x86.c | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b976903c925c..48bbc35bd246 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8142,6 +8142,7 @@ static int handle_invalid_op(struct kvm_vcpu *vcpu) static int handle_monitor_trap(struct kvm_vcpu *vcpu) { + kvmi_stop_ss(vcpu); return 1; } @@ -10681,6 +10682,11 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) } } + if (kvmi_vcpu_enabled_ss(vcpu) + && exit_reason != EXIT_REASON_EPT_VIOLATION + && exit_reason != EXIT_REASON_MONITOR_TRAP_FLAG) + kvmi_stop_ss(vcpu); + if (exit_reason < kvm_vmx_max_exit_handlers && kvm_vmx_exit_handlers[exit_reason]) return kvm_vmx_exit_handlers[exit_reason](vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b1cbcf44cf70..d163be11b2b5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7147,8 +7147,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool req_int_win) int r; /* try to reinject previous events if any */ - - if (vcpu->arch.exception.injected) + if (vcpu->arch.exception.injected && !kvmi_vcpu_enabled_ss(vcpu)) kvm_x86_ops->queue_exception(vcpu); /* * Do not inject an NMI or interrupt if there is a pending @@ -7184,7 +7183,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool req_int_win) } /* try to inject new event if pending */ - if (vcpu->arch.exception.pending) { + if (vcpu->arch.exception.pending && !kvmi_vcpu_enabled_ss(vcpu)) { WARN_ON_ONCE(vcpu->arch.exception.injected); vcpu->arch.exception.pending = false; vcpu->arch.exception.injected = true;