aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-05-11 06:35:48 -0400
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:57 -0400
commit923c61bbc6413e87e5f6b0bae663d202a8de0537 (patch)
treea4ae8262a60f343bedb29f06be8510a21ef11dc8 /arch/x86/kvm
parentfa9726b0733461781933ab7180aca45e46d0a891 (diff)
KVM: Remove irq_pending bitmap
Only one interrupt vector can be injected from userspace irqchip at any given time so no need to store it in a bitmap. Put it into interrupt queue directly. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/irq.c4
-rw-r--r--arch/x86/kvm/x86.c38
-rw-r--r--arch/x86/kvm/x86.h12
3 files changed, 13 insertions, 41 deletions
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index 11c2757b808f..96dfbb6ad2a9 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -50,7 +50,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
50 struct kvm_pic *s; 50 struct kvm_pic *s;
51 51
52 if (!irqchip_in_kernel(v->kvm)) 52 if (!irqchip_in_kernel(v->kvm))
53 return v->arch.irq_summary; 53 return v->arch.interrupt.pending;
54 54
55 if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ 55 if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
56 if (kvm_apic_accept_pic_intr(v)) { 56 if (kvm_apic_accept_pic_intr(v)) {
@@ -72,7 +72,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
72 int vector; 72 int vector;
73 73
74 if (!irqchip_in_kernel(v->kvm)) 74 if (!irqchip_in_kernel(v->kvm))
75 return kvm_pop_irq(v); 75 return v->arch.interrupt.nr;
76 76
77 vector = kvm_get_apic_interrupt(v); /* APIC */ 77 vector = kvm_get_apic_interrupt(v); /* APIC */
78 if (vector == -1) { 78 if (vector == -1) {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 96413f4e33ba..54eec3565485 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1441,8 +1441,7 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
1441 return -ENXIO; 1441 return -ENXIO;
1442 vcpu_load(vcpu); 1442 vcpu_load(vcpu);
1443 1443
1444 set_bit(irq->irq, vcpu->arch.irq_pending); 1444 kvm_queue_interrupt(vcpu, irq->irq);
1445 set_bit(irq->irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
1446 1445
1447 vcpu_put(vcpu); 1446 vcpu_put(vcpu);
1448 1447
@@ -3583,12 +3582,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
3583 sregs->efer = vcpu->arch.shadow_efer; 3582 sregs->efer = vcpu->arch.shadow_efer;
3584 sregs->apic_base = kvm_get_apic_base(vcpu); 3583 sregs->apic_base = kvm_get_apic_base(vcpu);
3585 3584
3586 if (irqchip_in_kernel(vcpu->kvm)) 3585 memset(sregs->interrupt_bitmap, 0, sizeof sregs->interrupt_bitmap);
3587 memset(sregs->interrupt_bitmap, 0,
3588 sizeof sregs->interrupt_bitmap);
3589 else
3590 memcpy(sregs->interrupt_bitmap, vcpu->arch.irq_pending,
3591 sizeof sregs->interrupt_bitmap);
3592 3586
3593 if (vcpu->arch.interrupt.pending) 3587 if (vcpu->arch.interrupt.pending)
3594 set_bit(vcpu->arch.interrupt.nr, 3588 set_bit(vcpu->arch.interrupt.nr,
@@ -4058,7 +4052,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
4058 struct kvm_sregs *sregs) 4052 struct kvm_sregs *sregs)
4059{ 4053{
4060 int mmu_reset_needed = 0; 4054 int mmu_reset_needed = 0;
4061 int i, pending_vec, max_bits; 4055 int pending_vec, max_bits;
4062 struct descriptor_table dt; 4056 struct descriptor_table dt;
4063 4057
4064 vcpu_load(vcpu); 4058 vcpu_load(vcpu);
@@ -4100,24 +4094,14 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
4100 if (mmu_reset_needed) 4094 if (mmu_reset_needed)
4101 kvm_mmu_reset_context(vcpu); 4095 kvm_mmu_reset_context(vcpu);
4102 4096
4103 if (!irqchip_in_kernel(vcpu->kvm)) { 4097 max_bits = (sizeof sregs->interrupt_bitmap) << 3;
4104 memcpy(vcpu->arch.irq_pending, sregs->interrupt_bitmap, 4098 pending_vec = find_first_bit(
4105 sizeof vcpu->arch.irq_pending); 4099 (const unsigned long *)sregs->interrupt_bitmap, max_bits);
4106 vcpu->arch.irq_summary = 0; 4100 if (pending_vec < max_bits) {
4107 for (i = 0; i < ARRAY_SIZE(vcpu->arch.irq_pending); ++i) 4101 kvm_queue_interrupt(vcpu, pending_vec);
4108 if (vcpu->arch.irq_pending[i]) 4102 pr_debug("Set back pending irq %d\n", pending_vec);
4109 __set_bit(i, &vcpu->arch.irq_summary); 4103 if (irqchip_in_kernel(vcpu->kvm))
4110 } else { 4104 kvm_pic_clear_isr_ack(vcpu->kvm);
4111 max_bits = (sizeof sregs->interrupt_bitmap) << 3;
4112 pending_vec = find_first_bit(
4113 (const unsigned long *)sregs->interrupt_bitmap,
4114 max_bits);
4115 /* Only pending external irq is handled here */
4116 if (pending_vec < max_bits) {
4117 kvm_queue_interrupt(vcpu, pending_vec);
4118 pr_debug("Set back pending irq %d\n", pending_vec);
4119 }
4120 kvm_pic_clear_isr_ack(vcpu->kvm);
4121 } 4105 }
4122 4106
4123 kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); 4107 kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 21203d421276..c1f1a8ceba64 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -19,18 +19,6 @@ static inline void kvm_clear_interrupt_queue(struct kvm_vcpu *vcpu)
19 vcpu->arch.interrupt.pending = false; 19 vcpu->arch.interrupt.pending = false;
20} 20}
21 21
22static inline u8 kvm_pop_irq(struct kvm_vcpu *vcpu)
23{
24 int word_index = __ffs(vcpu->arch.irq_summary);
25 int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
26 int irq = word_index * BITS_PER_LONG + bit_index;
27
28 clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
29 if (!vcpu->arch.irq_pending[word_index])
30 clear_bit(word_index, &vcpu->arch.irq_summary);
31 return irq;
32}
33
34static inline bool kvm_event_needs_reinjection(struct kvm_vcpu *vcpu) 22static inline bool kvm_event_needs_reinjection(struct kvm_vcpu *vcpu)
35{ 23{
36 return vcpu->arch.exception.pending || vcpu->arch.interrupt.pending || 24 return vcpu->arch.exception.pending || vcpu->arch.interrupt.pending ||