diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h index 4034f6576cd930f12b40313da7b03823350b433b..30adddcb182dd4ad3c51f8c08017de1df46f9574 100644 --- a/drivers/kvm/irq.h +++ b/drivers/kvm/irq.h @@ -61,7 +61,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *v); void kvm_pic_update_irq(struct kvm_pic *s); -#define IOAPIC_NUM_PINS 24 +#define IOAPIC_NUM_PINS KVM_IOAPIC_NUM_PINS #define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */ #define IOAPIC_EDGE_TRIG 0 #define IOAPIC_LEVEL_TRIG 1 diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index c270e4afd3fde3e472c4bd841a78e60b0f65cd3d..61dff55f137e2e67d55c369847ce9965f18135d5 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -913,6 +913,11 @@ static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) &pic_irqchip(kvm)->pics[1], sizeof(struct kvm_pic_state)); break; + case KVM_IRQCHIP_IOAPIC: + memcpy (&chip->chip.ioapic, + ioapic_irqchip(kvm), + sizeof(struct kvm_ioapic_state)); + break; default: r = -EINVAL; break; @@ -936,6 +941,11 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) &chip->chip.pic, sizeof(struct kvm_pic_state)); break; + case KVM_IRQCHIP_IOAPIC: + memcpy (ioapic_irqchip(kvm), + &chip->chip.ioapic, + sizeof(struct kvm_ioapic_state)); + break; default: r = -EINVAL; break; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 6560f11870fd9982753e0fdf17556b7135769eb3..42d15150d7a3275e728a4ffef5728c215a08a0d5 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -45,7 +45,7 @@ struct kvm_irq_level { __u32 level; }; -/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */ +/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */ struct kvm_pic_state { __u8 last_irr; /* edge detection */ __u8 irr; /* interrupt request register */ @@ -65,9 +65,35 @@ struct kvm_pic_state { __u8 elcr_mask; }; +#define KVM_IOAPIC_NUM_PINS 24 +struct kvm_ioapic_state { + __u64 base_address; + __u32 ioregsel; + __u32 id; + __u32 irr; + __u32 pad; + union { + __u64 bits; + struct { + __u8 vector; + __u8 delivery_mode:3; + __u8 dest_mode:1; + __u8 delivery_status:1; + __u8 polarity:1; + __u8 remote_irr:1; + __u8 trig_mode:1; + __u8 mask:1; + __u8 reserve:7; + __u8 reserved[4]; + __u8 dest_id; + } fields; + } redirtbl[KVM_IOAPIC_NUM_PINS]; +}; + enum kvm_irqchip_id { KVM_IRQCHIP_PIC_MASTER = 0, KVM_IRQCHIP_PIC_SLAVE = 1, + KVM_IRQCHIP_IOAPIC = 2, }; struct kvm_irqchip { @@ -76,6 +102,7 @@ struct kvm_irqchip { union { char dummy[512]; /* reserving space */ struct kvm_pic_state pic; + struct kvm_ioapic_state ioapic; } chip; };