lkml.org 
[lkml]   [2008]   [Apr]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 27/31] KVM: SVM: disable CR8 intercept when tpr is not masking interrupts
    Date
    From: Joerg Roedel <joerg.roedel@amd.com>

    This patch disables the intercept of CR8 writes if the TPR is not masking
    interrupts. This reduces the total number CR8 intercepts to below 1 percent of
    what we have without this patch using Windows 64 bit guests.

    Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
    Signed-off-by: Avi Kivity <avi@qumranet.com>
    ---
    arch/x86/kvm/svm.c | 31 +++++++++++++++++++++++++++----
    1 files changed, 27 insertions(+), 4 deletions(-)

    diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
    index ee2ee83..61bb2cb 100644
    --- a/arch/x86/kvm/svm.c
    +++ b/arch/x86/kvm/svm.c
    @@ -1502,6 +1502,27 @@ static void svm_set_irq(struct kvm_vcpu *vcpu, int irq)
    svm_inject_irq(svm, irq);
    }

    +static void update_cr8_intercept(struct kvm_vcpu *vcpu)
    +{
    + struct vcpu_svm *svm = to_svm(vcpu);
    + struct vmcb *vmcb = svm->vmcb;
    + int max_irr, tpr;
    +
    + if (!irqchip_in_kernel(vcpu->kvm) || vcpu->arch.apic->vapic_addr)
    + return;
    +
    + vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
    +
    + max_irr = kvm_lapic_find_highest_irr(vcpu);
    + if (max_irr == -1)
    + return;
    +
    + tpr = kvm_lapic_get_cr8(vcpu) << 4;
    +
    + if (tpr >= (max_irr & 0xf0))
    + vmcb->control.intercept_cr_write |= INTERCEPT_CR8_MASK;
    +}
    +
    static void svm_intr_assist(struct kvm_vcpu *vcpu)
    {
    struct vcpu_svm *svm = to_svm(vcpu);
    @@ -1514,14 +1535,14 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
    SVM_EVTINJ_VEC_MASK;
    vmcb->control.exit_int_info = 0;
    svm_inject_irq(svm, intr_vector);
    - return;
    + goto out;
    }

    if (vmcb->control.int_ctl & V_IRQ_MASK)
    - return;
    + goto out;

    if (!kvm_cpu_has_interrupt(vcpu))
    - return;
    + goto out;

    if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
    (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
    @@ -1529,12 +1550,14 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
    /* unable to deliver irq, set pending irq */
    vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
    svm_inject_irq(svm, 0x0);
    - return;
    + goto out;
    }
    /* Okay, we can deliver the interrupt: grab it and update PIC state. */
    intr_vector = kvm_cpu_get_interrupt(vcpu);
    svm_inject_irq(svm, intr_vector);
    kvm_timer_intr_post(vcpu, intr_vector);
    +out:
    + update_cr8_intercept(vcpu);
    }

    static void kvm_reput_irq(struct vcpu_svm *svm)
    --
    1.5.5


    \
     
     \ /
      Last update: 2008-04-21 12:43    [W:0.028 / U:2.648 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site