static void kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, int level) { #ifdef CONFIG_X86 kvm_pic_set_irq(pic_irqchip(kvm), e->irqchip.pin, level); #endif }
void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) { int i; ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); mutex_lock(&kvm->irq_lock); if (irq_source_id < 0 || irq_source_id >= BITS_PER_LONG) { printk(KERN_ERR "kvm: IRQ source ID out of range!\n"); goto unlock; } clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap); if (!irqchip_in_kernel(kvm)) goto unlock; for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++) { clear_bit(irq_source_id, &kvm->arch.vioapic->irq_states[i]); if (i >= 16) continue; #ifdef CONFIG_X86 clear_bit(irq_source_id, &pic_irqchip(kvm)->irq_states[i]); #endif } unlock: mutex_unlock(&kvm->irq_lock); }
/* * check if there is pending interrupt from * non-APIC source without intack. */ static int kvm_cpu_has_extint(struct kvm_vcpu *v) { if (kvm_apic_accept_pic_intr(v)) return pic_irqchip(v->kvm)->output; /* PIC */ else return 0; }
/* This should be called with the kvm->lock mutex held */ void kvm_set_irq(struct kvm *kvm, int irq, int level) { /* Not possible to detect if the guest uses the PIC or the * IOAPIC. So set the bit in both. The guest will ignore * writes to the unused one. */ kvm_ioapic_set_irq(kvm->arch.vioapic, irq, level); #ifdef CONFIG_X86 kvm_pic_set_irq(pic_irqchip(kvm), irq, level); #endif }
static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, int irq_source_id, int level, bool line_status) { #ifdef CONFIG_X86 struct kvm_pic *pic = pic_irqchip(kvm); return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); #else return -1; #endif }
/* * check if there is pending interrupt from * non-APIC source without intack. */ static int kvm_cpu_has_extint(struct kvm_vcpu *v) { u8 accept = kvm_apic_accept_pic_intr(v); if (accept) { if (irqchip_split(v->kvm)) return pending_userspace_extint(v); else return pic_irqchip(v->kvm)->output; } else return 0; }
/* * check if there is pending interrupt without * intack. */ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) { struct kvm_pic *s; if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ if (kvm_apic_accept_pic_intr(v)) { s = pic_irqchip(v->kvm); /* PIC */ return s->output; } else return 0; } return 1; }
/* * Read pending interrupt vector and intack. */ int kvm_cpu_get_interrupt(struct kvm_vcpu *v) { struct kvm_pic *s; int vector; vector = kvm_get_apic_interrupt(v); /* APIC */ if (vector == -1) { if (kvm_apic_accept_pic_intr(v)) { s = pic_irqchip(v->kvm); s->output = 0; /* PIC */ vector = kvm_pic_read_irq(s); } } return vector; }
/* * check if there is pending interrupt without * intack. */ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) { struct kvm_pic *s; if (!irqchip_in_kernel(v->kvm)) return v->arch.interrupt.pending; if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ if (kvm_apic_accept_pic_intr(v)) { s = pic_irqchip(v->kvm); /* PIC */ return s->output; } else return 0; } return 1; }
void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) { ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); #ifdef CONFIG_X86 ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); #endif mutex_lock(&kvm->irq_lock); if (irq_source_id < 0 || irq_source_id >= BITS_PER_LONG) { printk(KERN_ERR "kvm: IRQ source ID out of range!\n"); goto unlock; } clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap); if (!irqchip_in_kernel(kvm)) goto unlock; kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id); #ifdef CONFIG_X86 kvm_pic_clear_all(pic_irqchip(kvm), irq_source_id); #endif unlock: mutex_unlock(&kvm->irq_lock); }