Commit aaacfc9a authored by Joerg Roedel's avatar Joerg Roedel Committed by Avi Kivity

KVM: SVM: disable CR8 intercept when tpr is not masking interrupts

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: default avatarJoerg Roedel <joerg.roedel@amd.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent d7bf8221
...@@ -1502,6 +1502,27 @@ static void svm_set_irq(struct kvm_vcpu *vcpu, int irq) ...@@ -1502,6 +1502,27 @@ static void svm_set_irq(struct kvm_vcpu *vcpu, int irq)
svm_inject_irq(svm, 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) static void svm_intr_assist(struct kvm_vcpu *vcpu)
{ {
struct vcpu_svm *svm = to_svm(vcpu); struct vcpu_svm *svm = to_svm(vcpu);
...@@ -1514,14 +1535,14 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu) ...@@ -1514,14 +1535,14 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
SVM_EVTINJ_VEC_MASK; SVM_EVTINJ_VEC_MASK;
vmcb->control.exit_int_info = 0; vmcb->control.exit_int_info = 0;
svm_inject_irq(svm, intr_vector); svm_inject_irq(svm, intr_vector);
return; goto out;
} }
if (vmcb->control.int_ctl & V_IRQ_MASK) if (vmcb->control.int_ctl & V_IRQ_MASK)
return; goto out;
if (!kvm_cpu_has_interrupt(vcpu)) if (!kvm_cpu_has_interrupt(vcpu))
return; goto out;
if (!(vmcb->save.rflags & X86_EFLAGS_IF) || if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) || (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
...@@ -1529,12 +1550,14 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu) ...@@ -1529,12 +1550,14 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
/* unable to deliver irq, set pending irq */ /* unable to deliver irq, set pending irq */
vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR); vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
svm_inject_irq(svm, 0x0); svm_inject_irq(svm, 0x0);
return; goto out;
} }
/* Okay, we can deliver the interrupt: grab it and update PIC state. */ /* Okay, we can deliver the interrupt: grab it and update PIC state. */
intr_vector = kvm_cpu_get_interrupt(vcpu); intr_vector = kvm_cpu_get_interrupt(vcpu);
svm_inject_irq(svm, intr_vector); svm_inject_irq(svm, intr_vector);
kvm_timer_intr_post(vcpu, intr_vector); kvm_timer_intr_post(vcpu, intr_vector);
out:
update_cr8_intercept(vcpu);
} }
static void kvm_reput_irq(struct vcpu_svm *svm) static void kvm_reput_irq(struct vcpu_svm *svm)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment