Skip to content

Commit

Permalink
KVM: Remove irq_pending bitmap
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Gleb Natapov authored and Avi Kivity committed Jun 10, 2009
1 parent fa9726b commit 923c61b
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 43 deletions.
2 changes: 0 additions & 2 deletions arch/x86/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,6 @@ struct kvm_mmu {

struct kvm_vcpu_arch {
u64 host_tsc;
unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */
DECLARE_BITMAP(irq_pending, KVM_NR_INTERRUPTS);
/*
* rip and regs accesses must go through
* kvm_{register,rip}_{read,write} functions.
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kvm/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
struct kvm_pic *s;

if (!irqchip_in_kernel(v->kvm))
return v->arch.irq_summary;
return v->arch.interrupt.pending;

if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
if (kvm_apic_accept_pic_intr(v)) {
Expand All @@ -72,7 +72,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
int vector;

if (!irqchip_in_kernel(v->kvm))
return kvm_pop_irq(v);
return v->arch.interrupt.nr;

vector = kvm_get_apic_interrupt(v); /* APIC */
if (vector == -1) {
Expand Down
38 changes: 11 additions & 27 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -1441,8 +1441,7 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
return -ENXIO;
vcpu_load(vcpu);

set_bit(irq->irq, vcpu->arch.irq_pending);
set_bit(irq->irq / BITS_PER_LONG, &vcpu->arch.irq_summary);
kvm_queue_interrupt(vcpu, irq->irq);

vcpu_put(vcpu);

Expand Down Expand Up @@ -3583,12 +3582,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
sregs->efer = vcpu->arch.shadow_efer;
sregs->apic_base = kvm_get_apic_base(vcpu);

if (irqchip_in_kernel(vcpu->kvm))
memset(sregs->interrupt_bitmap, 0,
sizeof sregs->interrupt_bitmap);
else
memcpy(sregs->interrupt_bitmap, vcpu->arch.irq_pending,
sizeof sregs->interrupt_bitmap);
memset(sregs->interrupt_bitmap, 0, sizeof sregs->interrupt_bitmap);

if (vcpu->arch.interrupt.pending)
set_bit(vcpu->arch.interrupt.nr,
Expand Down Expand Up @@ -4058,7 +4052,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
struct kvm_sregs *sregs)
{
int mmu_reset_needed = 0;
int i, pending_vec, max_bits;
int pending_vec, max_bits;
struct descriptor_table dt;

vcpu_load(vcpu);
Expand Down Expand Up @@ -4100,24 +4094,14 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
if (mmu_reset_needed)
kvm_mmu_reset_context(vcpu);

if (!irqchip_in_kernel(vcpu->kvm)) {
memcpy(vcpu->arch.irq_pending, sregs->interrupt_bitmap,
sizeof vcpu->arch.irq_pending);
vcpu->arch.irq_summary = 0;
for (i = 0; i < ARRAY_SIZE(vcpu->arch.irq_pending); ++i)
if (vcpu->arch.irq_pending[i])
__set_bit(i, &vcpu->arch.irq_summary);
} else {
max_bits = (sizeof sregs->interrupt_bitmap) << 3;
pending_vec = find_first_bit(
(const unsigned long *)sregs->interrupt_bitmap,
max_bits);
/* Only pending external irq is handled here */
if (pending_vec < max_bits) {
kvm_queue_interrupt(vcpu, pending_vec);
pr_debug("Set back pending irq %d\n", pending_vec);
}
kvm_pic_clear_isr_ack(vcpu->kvm);
max_bits = (sizeof sregs->interrupt_bitmap) << 3;
pending_vec = find_first_bit(
(const unsigned long *)sregs->interrupt_bitmap, max_bits);
if (pending_vec < max_bits) {
kvm_queue_interrupt(vcpu, pending_vec);
pr_debug("Set back pending irq %d\n", pending_vec);
if (irqchip_in_kernel(vcpu->kvm))
kvm_pic_clear_isr_ack(vcpu->kvm);
}

kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
Expand Down
12 changes: 0 additions & 12 deletions arch/x86/kvm/x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ static inline void kvm_clear_interrupt_queue(struct kvm_vcpu *vcpu)
vcpu->arch.interrupt.pending = false;
}

static inline u8 kvm_pop_irq(struct kvm_vcpu *vcpu)
{
int word_index = __ffs(vcpu->arch.irq_summary);
int bit_index = __ffs(vcpu->arch.irq_pending[word_index]);
int irq = word_index * BITS_PER_LONG + bit_index;

clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
if (!vcpu->arch.irq_pending[word_index])
clear_bit(word_index, &vcpu->arch.irq_summary);
return irq;
}

static inline bool kvm_event_needs_reinjection(struct kvm_vcpu *vcpu)
{
return vcpu->arch.exception.pending || vcpu->arch.interrupt.pending ||
Expand Down

0 comments on commit 923c61b

Please sign in to comment.