xref: /kvmtool/irq.c (revision 5f0a22b7f8012b2b51b0aea2874d94f6f8355f8a)
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 IRQ_MAX_GSI			64
15 #define IRQCHIP_MASTER			0
16 #define IRQCHIP_SLAVE			1
17 #define IRQCHIP_IOAPIC			2
18 
19 static u8		next_line	= 3;
20 static u8		next_dev	= 1;
21 static struct rb_root	pci_tree	= RB_ROOT;
22 
23 /* First 24 GSIs are routed between IRQCHIPs and IOAPICs */
24 static u32 gsi = 24;
25 
26 struct kvm_irq_routing *irq_routing;
27 
28 static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin)
29 {
30 	if (gsi >= IRQ_MAX_GSI)
31 		return -ENOSPC;
32 
33 	irq_routing->entries[irq_routing->nr++] =
34 		(struct kvm_irq_routing_entry) {
35 			.gsi = gsi,
36 			.type = type,
37 			.u.irqchip.irqchip = irqchip,
38 			.u.irqchip.pin = pin,
39 		};
40 
41 	return 0;
42 }
43 
44 static struct pci_dev *search(struct rb_root *root, u32 id)
45 {
46 	struct rb_node *node = root->rb_node;
47 
48 	while (node) {
49 		struct pci_dev *data = container_of(node, struct pci_dev, node);
50 		int result;
51 
52 		result = id - data->id;
53 
54 		if (result < 0)
55 			node = node->rb_left;
56 		else if (result > 0)
57 			node = node->rb_right;
58 		else
59 			return data;
60 	}
61 	return NULL;
62 }
63 
64 static int insert(struct rb_root *root, struct pci_dev *data)
65 {
66 	struct rb_node **new = &(root->rb_node), *parent = NULL;
67 
68 	/* Figure out where to put new node */
69 	while (*new) {
70 		struct pci_dev *this	= container_of(*new, struct pci_dev, node);
71 		int result		= data->id - this->id;
72 
73 		parent = *new;
74 		if (result < 0)
75 			new = &((*new)->rb_left);
76 		else if (result > 0)
77 			new = &((*new)->rb_right);
78 		else
79 			return 0;
80 	}
81 
82 	/* Add new node and rebalance tree. */
83 	rb_link_node(&data->node, parent, new);
84 	rb_insert_color(&data->node, root);
85 
86 	return 1;
87 }
88 
89 int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line)
90 {
91 	struct pci_dev *node;
92 
93 	node = search(&pci_tree, dev);
94 
95 	if (!node) {
96 		/* We haven't found a node - First device of it's kind */
97 		node = malloc(sizeof(*node));
98 		if (node == NULL)
99 			return -1;
100 
101 		*node = (struct pci_dev) {
102 			.id	= dev,
103 			/*
104 			 * PCI supports only INTA#,B#,C#,D# per device.
105 			 * A#,B#,C#,D# are allowed for multifunctional
106 			 * devices so stick with A# for our single
107 			 * function devices.
108 			 */
109 			.pin	= 1,
110 		};
111 
112 		INIT_LIST_HEAD(&node->lines);
113 
114 		if (insert(&pci_tree, node) != 1) {
115 			free(node);
116 			return -1;
117 		}
118 	}
119 
120 	if (node) {
121 		/* This device already has a pin assigned, give out a new line and device id */
122 		struct irq_line *new = malloc(sizeof(*new));
123 		if (new == NULL)
124 			return -1;
125 
126 		new->line	= next_line++;
127 		*line		= new->line;
128 		*pin		= node->pin;
129 		*num		= next_dev++;
130 
131 		list_add(&new->node, &node->lines);
132 
133 		return 0;
134 	}
135 
136 	return -1;
137 }
138 
139 void irq__init(struct kvm *kvm)
140 {
141 	int i, r;
142 
143 	irq_routing = malloc(sizeof(struct kvm_irq_routing) +
144 			IRQ_MAX_GSI * sizeof(struct kvm_irq_routing_entry));
145 	if (irq_routing == NULL)
146 		die("Failed allocating space for GSI table");
147 
148 	/* Hook first 8 GSIs to master IRQCHIP */
149 	for (i = 0; i < 8; i++)
150 		irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_MASTER, i);
151 
152 	/* Hook next 8 GSIs to slave IRQCHIP */
153 	for (i = 8; i < 16; i++)
154 		irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_SLAVE, 8-i);
155 
156 	/* Last but not least, IOAPIC */
157 	for (i = 0; i < 24; i++) {
158 		if (i == 0)
159 			irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, 2);
160 		else
161 			irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, i);
162 	}
163 
164 	r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing);
165 	if (r)
166 		die("Failed setting GSI routes");
167 }
168 
169 int irq__add_msix_route(struct kvm *kvm, u32 low, u32 high, u32 data)
170 {
171 	int r;
172 
173 	irq_routing->entries[irq_routing->nr++] =
174 		(struct kvm_irq_routing_entry) {
175 			.gsi = gsi,
176 			.type = KVM_IRQ_ROUTING_MSI,
177 			.u.msi.address_lo = low,
178 			.u.msi.address_hi = high,
179 			.u.msi.data = data,
180 		};
181 
182 	r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing);
183 	if (r)
184 		return r;
185 
186 	return gsi++;
187 }
188 
189 struct rb_node *irq__get_pci_tree(void)
190 {
191 	return rb_first(&pci_tree);
192 }
193