1 #include "kvm/irq.h"
2 #include "kvm/kvm.h"
3 #include "kvm/util.h"
4
5 #include <linux/types.h>
6 #include <linux/rbtree.h>
7 #include <linux/list.h>
8 #include <linux/kvm.h>
9 #include <sys/ioctl.h>
10
11 #include <stddef.h>
12 #include <stdlib.h>
13
14 #define IRQCHIP_MASTER 0
15 #define IRQCHIP_SLAVE 1
16 #define IRQCHIP_IOAPIC 2
17
irq__add_routing(u32 gsi,u32 type,u32 irqchip,u32 pin)18 static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin)
19 {
20 int r = irq__allocate_routing_entry();
21 if (r)
22 return r;
23
24 irq_routing->entries[irq_routing->nr++] =
25 (struct kvm_irq_routing_entry) {
26 .gsi = gsi,
27 .type = type,
28 .u.irqchip.irqchip = irqchip,
29 .u.irqchip.pin = pin,
30 };
31
32 return 0;
33 }
34
irq__init(struct kvm * kvm)35 int irq__init(struct kvm *kvm)
36 {
37 int i, r;
38
39 /* Hook first 8 GSIs to master IRQCHIP */
40 for (i = 0; i < 8; i++)
41 if (i != 2)
42 irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_MASTER, i);
43
44 /* Hook next 8 GSIs to slave IRQCHIP */
45 for (i = 8; i < 16; i++)
46 irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_SLAVE, i - 8);
47
48 /* Last but not least, IOAPIC */
49 for (i = 0; i < 24; i++) {
50 if (i == 0)
51 irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, 2);
52 else if (i != 2)
53 irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, i);
54 }
55
56 r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing);
57 if (r) {
58 free(irq_routing);
59 return errno;
60 }
61
62 next_gsi = i;
63
64 return 0;
65 }
66 dev_base_init(irq__init);
67