diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-05-11 06:35:48 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:57 -0400 |
commit | 923c61bbc6413e87e5f6b0bae663d202a8de0537 (patch) | |
tree | a4ae8262a60f343bedb29f06be8510a21ef11dc8 | |
parent | fa9726b0733461781933ab7180aca45e46d0a891 (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>
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/irq.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 38 | ||||
-rw-r--r-- | arch/x86/kvm/x86.h | 12 |
4 files changed, 13 insertions, 43 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 16d1481aa231..977a785a9d75 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -266,8 +266,6 @@ struct kvm_mmu { | |||
266 | 266 | ||
267 | struct kvm_vcpu_arch { | 267 | struct kvm_vcpu_arch { |
268 | u64 host_tsc; | 268 | u64 host_tsc; |
269 | unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */ | ||
270 | DECLARE_BITMAP(irq_pending, KVM_NR_INTERRUPTS); | ||
271 | /* | 269 | /* |
272 | * rip and regs accesses must go through | 270 | * rip and regs accesses must go through |
273 | * kvm_{register,rip}_{read,write} functions. | 271 | * kvm_{register,rip}_{read,write} functions. |
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 | ||
22 | static 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 | |||
34 | static inline bool kvm_event_needs_reinjection(struct kvm_vcpu *vcpu) | 22 | static 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 || |