xref: /kvmtool/x86/irq.c (revision 8ccc85497ca3136688b015fecaa956fd95b936a1)
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