KVM: Move IO APIC to its own lock
The allows removal of irq_lock from the injection path. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
@@ -38,7 +38,15 @@ static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
|
||||
s->isr_ack |= (1 << irq);
|
||||
if (s != &s->pics_state->pics[0])
|
||||
irq += 8;
|
||||
/*
|
||||
* We are dropping lock while calling ack notifiers since ack
|
||||
* notifier callbacks for assigned devices call into PIC recursively.
|
||||
* Other interrupt may be delivered to PIC while lock is dropped but
|
||||
* it should be safe since PIC state is already updated at this stage.
|
||||
*/
|
||||
spin_unlock(&s->pics_state->lock);
|
||||
kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq);
|
||||
spin_lock(&s->pics_state->lock);
|
||||
}
|
||||
|
||||
void kvm_pic_clear_isr_ack(struct kvm *kvm)
|
||||
@@ -176,16 +184,18 @@ int kvm_pic_set_irq(void *opaque, int irq, int level)
|
||||
static inline void pic_intack(struct kvm_kpic_state *s, int irq)
|
||||
{
|
||||
s->isr |= 1 << irq;
|
||||
if (s->auto_eoi) {
|
||||
if (s->rotate_on_auto_eoi)
|
||||
s->priority_add = (irq + 1) & 7;
|
||||
pic_clear_isr(s, irq);
|
||||
}
|
||||
/*
|
||||
* We don't clear a level sensitive interrupt here
|
||||
*/
|
||||
if (!(s->elcr & (1 << irq)))
|
||||
s->irr &= ~(1 << irq);
|
||||
|
||||
if (s->auto_eoi) {
|
||||
if (s->rotate_on_auto_eoi)
|
||||
s->priority_add = (irq + 1) & 7;
|
||||
pic_clear_isr(s, irq);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int kvm_pic_read_irq(struct kvm *kvm)
|
||||
@@ -294,9 +304,9 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
|
||||
priority = get_priority(s, s->isr);
|
||||
if (priority != 8) {
|
||||
irq = (priority + s->priority_add) & 7;
|
||||
pic_clear_isr(s, irq);
|
||||
if (cmd == 5)
|
||||
s->priority_add = (irq + 1) & 7;
|
||||
pic_clear_isr(s, irq);
|
||||
pic_update_irq(s->pics_state);
|
||||
}
|
||||
break;
|
||||
|
Reference in New Issue
Block a user