Re: [PATCH v4 1/6] KVM: Check for pending events before attempting injection

Marcelo Tosatti
2010-08-30T17:51:35Z

On Mon, Aug 30, 2010 at 02:36:57PM +0300, Avi Kivity wrote:
> Instead of blindly attempting to inject an event before each guest entry,
> check for a possible event first in vcpu->requests. Sites that can trigger
> event injection are modified to set KVM_REQ_EVENT:
>
> - interrupt, nmi window opening
> - ppr updates
> - i8259 output changes
> - local apic irr changes
> - rflags updates
> - gif flag set
> - event set on exit
>
> This improves non-injecting entry performance, and sets the stage for
> non-atomic injection.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
> arch/x86/kvm/i8259.c | 1 +
> arch/x86/kvm/lapic.c | 13 +++++++++++--
> arch/x86/kvm/svm.c | 8 +++++++-
> arch/x86/kvm/vmx.c | 6 ++++++
> arch/x86/kvm/x86.c | 35 ++++++++++++++++++++++++++---------
> include/linux/kvm_host.h | 1 +
> 6 files changed, 52 insertions(+), 12 deletions(-)
>

> index cc6d6cd..907ea7f 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -284,6 +284,8 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
> u32 prev_nr;
> int class1, class2;
>
> + kvm_make_request(KVM_REQ_EVENT, vcpu);
> +
> if (!vcpu->arch.exception.pending) {
> queue:
> vcpu->arch.exception.pending = true;
> @@ -339,6 +341,7 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
>
> void kvm_inject_nmi(struct kvm_vcpu *vcpu)
> {
> + kvm_make_request(KVM_REQ_EVENT, vcpu);
> vcpu->arch.nmi_pending = 1;
> }
> EXPORT_SYMBOL_GPL(kvm_inject_nmi);
> @@ -2470,6 +2473,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
> if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR)
> vcpu->arch.sipi_vector = events->sipi_vector;
>
> + kvm_make_request(KVM_REQ_EVENT, vcpu);
> +
> return 0;
> }
>
> @@ -4201,6 +4206,7 @@ restart:
>
> toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility);
> kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
> + kvm_make_request(KVM_REQ_EVENT, vcpu);
> memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
> kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
>
> @@ -4927,17 +4933,19 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
> goto out;
> }
>
> - inject_pending_event(vcpu);
> + if (kvm_check_request(KVM_REQ_EVENT, vcpu)) {
> + inject_pending_event(vcpu);
>
> - /* enable NMI/IRQ window open exits if needed */
> - if (vcpu->arch.nmi_pending)
> - kvm_x86_ops->enable_nmi_window(vcpu);
> - else if (kvm_cpu_has_interrupt(vcpu) || req_int_win)
> - kvm_x86_ops->enable_irq_window(vcpu);
> + /* enable NMI/IRQ window open exits if needed */
> + if (vcpu->arch.nmi_pending)
> + kvm_x86_ops->enable_nmi_window(vcpu);
> + else if (kvm_cpu_has_interrupt(vcpu) || req_int_win)
> + kvm_x86_ops->enable_irq_window(vcpu);

Misses req_int_win == true.

Looks good otherwise.