This patch changes the PIC interrupts delivery. Now it is only deliverd
to vcpu0 when either condition is met (on vcpu0):
  1. local APIC is hardware disabled
  2. LVT0 is unmasked and configured to delivery mode ExtInt

It fixes the 2x faster wall clock on x86_64 and SMP i386 Linux guests

Signed-off-by: Qing He <[EMAIL PROTECTED]>

---
 drivers/kvm/irq.c   |    4 ++--
 drivers/kvm/irq.h   |    1 +
 drivers/kvm/lapic.c |   17 +++++++++++++++++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/irq.c b/drivers/kvm/irq.c
index 608c530..0f663fe 100644
--- a/drivers/kvm/irq.c
+++ b/drivers/kvm/irq.c
@@ -33,7 +33,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
        struct kvm_pic *s;
 
        if (kvm_apic_has_interrupt(v) == -1) {  /* LAPIC */
-               if (v->vcpu_id == 0) {
+               if (kvm_apic_accept_pic_intr(v)) {
                        s = pic_irqchip(v->kvm);        /* PIC */
                        return s->output;
                } else
@@ -53,7 +53,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
 
        vector = kvm_get_apic_interrupt(v);     /* APIC */
        if (vector == -1) {
-               if (v->vcpu_id == 0) {
+               if (kvm_apic_accept_pic_intr(v)) {
                        s = pic_irqchip(v->kvm);
                        s->output = 0;          /* PIC */
                        vector = kvm_pic_read_irq(s);
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 5f97e25..11fc014 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -135,6 +135,7 @@ do {
\
 
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
 int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu);
+int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu);
 int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu);
 int kvm_create_lapic(struct kvm_vcpu *vcpu);
 void kvm_lapic_reset(struct kvm_vcpu *vcpu);
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index 472a1c7..ddf9f20 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -836,6 +836,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
 
        for (i = 0; i < APIC_LVT_NUM; i++)
                apic_set_reg(apic, APIC_LVTT + 0x10 * i,
APIC_LVT_MASKED);
+       apic_set_reg(apic, APIC_LVT0,
+                    SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
 
        apic_set_reg(apic, APIC_DFR, 0xffffffffU);
        apic_set_reg(apic, APIC_SPIV, 0xff);
@@ -984,6 +986,21 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
        return highest_irr;
 }
 
+int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu)
+{
+       u32 lvt0 = apic_get_reg(vcpu->apic, APIC_LVT0);
+       int r = 0;
+
+       if (vcpu->vcpu_id == 0) {
+               if (!apic_hw_enabled(vcpu->apic))
+                       r = 1;
+               if ((lvt0 & APIC_LVT_MASKED) == 0 &&
+                   GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT)
+                       r = 1;
+       }
+       return r;
+}
+
 void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
 {
        struct kvm_lapic *apic = vcpu->apic;
-- 
1.5.1.2

Attachment: 0001-kvm-apic-accept-pic-intr.patch
Description: 0001-kvm-apic-accept-pic-intr.patch

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to