提交 aaacfc9a 编写于 作者: J Joerg Roedel 提交者: 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: NJoerg Roedel <joerg.roedel@amd.com>
Signed-off-by: NAvi Kivity <avi@qumranet.com>
上级 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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册