*/
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include <trace/events/kvm.h>
#include <asm/msidef.h>
int irq_source_id;
mutex_lock(&kvm->irq_lock);
- irq_source_id = find_first_zero_bit(bitmap,
- sizeof(kvm->arch.irq_sources_bitmap));
+ irq_source_id = find_first_zero_bit(bitmap, BITS_PER_LONG);
- if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
+ if (irq_source_id >= BITS_PER_LONG) {
printk(KERN_WARNING "kvm: exhaust allocatable IRQ sources!\n");
- return -EFAULT;
+ irq_source_id = -EFAULT;
+ goto unlock;
}
ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
set_bit(irq_source_id, bitmap);
+unlock:
mutex_unlock(&kvm->irq_lock);
return irq_source_id;
mutex_lock(&kvm->irq_lock);
if (irq_source_id < 0 ||
- irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
+ irq_source_id >= BITS_PER_LONG) {
printk(KERN_ERR "kvm: IRQ source ID out of range!\n");
- return;
+ 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)
clear_bit(irq_source_id, &pic_irqchip(kvm)->irq_states[i]);
#endif
}
- clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
+unlock:
mutex_unlock(&kvm->irq_lock);
}
{
int r = -EINVAL;
int delta;
+ unsigned max_pin;
struct kvm_kernel_irq_routing_entry *ei;
struct hlist_node *n;
switch (ue->u.irqchip.irqchip) {
case KVM_IRQCHIP_PIC_MASTER:
e->set = kvm_set_pic_irq;
+ max_pin = 16;
break;
case KVM_IRQCHIP_PIC_SLAVE:
e->set = kvm_set_pic_irq;
+ max_pin = 16;
delta = 8;
break;
case KVM_IRQCHIP_IOAPIC:
+ max_pin = KVM_IOAPIC_NUM_PINS;
e->set = kvm_set_ioapic_irq;
break;
default:
}
e->irqchip.irqchip = ue->u.irqchip.irqchip;
e->irqchip.pin = ue->u.irqchip.pin + delta;
- if (e->irqchip.pin >= KVM_IOAPIC_NUM_PINS)
+ if (e->irqchip.pin >= max_pin)
goto out;
rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi;
break;