xref: /kvmtool/virtio/pci.c (revision 657ee18b9cca2960ea953e4eabc6898668363c34)
1 #include "kvm/virtio-pci.h"
2 
3 #include "kvm/ioport.h"
4 #include "kvm/kvm.h"
5 #include "kvm/virtio-pci-dev.h"
6 #include "kvm/irq.h"
7 #include "kvm/virtio.h"
8 #include "kvm/ioeventfd.h"
9 #include "kvm/virtio-trans.h"
10 
11 #include <linux/virtio_pci.h>
12 #include <string.h>
13 
14 struct virtio_trans_ops *virtio_pci__get_trans_ops(void)
15 {
16 	static struct virtio_trans_ops virtio_pci_trans = (struct virtio_trans_ops) {
17 		.signal_vq	= virtio_pci__signal_vq,
18 		.signal_config	= virtio_pci__signal_config,
19 		.init		= virtio_pci__init,
20 	};
21 	return &virtio_pci_trans;
22 };
23 
24 static void virtio_pci__ioevent_callback(struct kvm *kvm, void *param)
25 {
26 	struct virtio_pci_ioevent_param *ioeventfd = param;
27 	struct virtio_pci *vpci = ioeventfd->vtrans->virtio;
28 
29 	ioeventfd->vtrans->virtio_ops->notify_vq(kvm, vpci->dev, ioeventfd->vq);
30 }
31 
32 static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
33 {
34 	struct ioevent ioevent;
35 	struct virtio_pci *vpci = vtrans->virtio;
36 
37 	vpci->ioeventfds[vq] = (struct virtio_pci_ioevent_param) {
38 		.vtrans		= vtrans,
39 		.vq		= vq,
40 	};
41 
42 	ioevent = (struct ioevent) {
43 		.io_addr	= vpci->base_addr + VIRTIO_PCI_QUEUE_NOTIFY,
44 		.io_len		= sizeof(u16),
45 		.fn		= virtio_pci__ioevent_callback,
46 		.fn_ptr		= &vpci->ioeventfds[vq],
47 		.datamatch	= vq,
48 		.fn_kvm		= kvm,
49 		.fd		= eventfd(0, 0),
50 	};
51 
52 	ioeventfd__add_event(&ioevent);
53 
54 	if (vtrans->virtio_ops->notify_vq_eventfd)
55 		vtrans->virtio_ops->notify_vq_eventfd(kvm, vpci->dev, vq, ioevent.fd);
56 
57 	return 0;
58 }
59 
60 static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
61 {
62 	return vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_ENABLE;
63 }
64 
65 static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
66 					void *data, int size, int offset)
67 {
68 	u32 config_offset;
69 	struct virtio_pci *vpci = vtrans->virtio;
70 	int type = virtio__get_dev_specific_field(offset - 20,
71 							virtio_pci__msix_enabled(vpci),
72 							&config_offset);
73 	if (type == VIRTIO_PCI_O_MSIX) {
74 		switch (offset) {
75 		case VIRTIO_MSI_CONFIG_VECTOR:
76 			ioport__write16(data, vpci->config_vector);
77 			break;
78 		case VIRTIO_MSI_QUEUE_VECTOR:
79 			ioport__write16(data, vpci->vq_vector[vpci->queue_selector]);
80 			break;
81 		};
82 
83 		return true;
84 	} else if (type == VIRTIO_PCI_O_CONFIG) {
85 		u8 cfg;
86 
87 		cfg = vtrans->virtio_ops->get_config(kvm, vpci->dev, config_offset);
88 		ioport__write8(data, cfg);
89 		return true;
90 	}
91 
92 	return false;
93 }
94 
95 static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
96 {
97 	unsigned long offset;
98 	bool ret = true;
99 	struct virtio_trans *vtrans;
100 	struct virtio_pci *vpci;
101 	u32 val;
102 
103 	vtrans = ioport->priv;
104 	vpci = vtrans->virtio;
105 	offset = port - vpci->base_addr;
106 
107 	switch (offset) {
108 	case VIRTIO_PCI_HOST_FEATURES:
109 		val = vtrans->virtio_ops->get_host_features(kvm, vpci->dev);
110 		ioport__write32(data, val);
111 		break;
112 	case VIRTIO_PCI_QUEUE_PFN:
113 		val = vtrans->virtio_ops->get_pfn_vq(kvm, vpci->dev, vpci->queue_selector);
114 		ioport__write32(data, val);
115 		break;
116 	case VIRTIO_PCI_QUEUE_NUM:
117 		val = vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
118 		ioport__write16(data, val);
119 		break;
120 	case VIRTIO_PCI_STATUS:
121 		ioport__write8(data, vpci->status);
122 		break;
123 	case VIRTIO_PCI_ISR:
124 		ioport__write8(data, vpci->isr);
125 		kvm__irq_line(kvm, vpci->pci_hdr.irq_line, VIRTIO_IRQ_LOW);
126 		vpci->isr = VIRTIO_IRQ_LOW;
127 		break;
128 	default:
129 		ret = virtio_pci__specific_io_in(kvm, vtrans, port, data, size, offset);
130 		break;
131 	};
132 
133 	return ret;
134 }
135 
136 static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
137 					void *data, int size, int offset)
138 {
139 	struct virtio_pci *vpci = vtrans->virtio;
140 	u32 config_offset, gsi, vec;
141 	int type = virtio__get_dev_specific_field(offset - 20, virtio_pci__msix_enabled(vpci),
142 							&config_offset);
143 	if (type == VIRTIO_PCI_O_MSIX) {
144 		switch (offset) {
145 		case VIRTIO_MSI_CONFIG_VECTOR:
146 			vec = vpci->config_vector = ioport__read16(data);
147 
148 			gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg);
149 
150 			vpci->config_gsi = gsi;
151 			break;
152 		case VIRTIO_MSI_QUEUE_VECTOR: {
153 			vec = vpci->vq_vector[vpci->queue_selector] = ioport__read16(data);
154 
155 			gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg);
156 			vpci->gsis[vpci->queue_selector] = gsi;
157 			if (vtrans->virtio_ops->notify_vq_gsi)
158 				vtrans->virtio_ops->notify_vq_gsi(kvm, vpci->dev,
159 							vpci->queue_selector, gsi);
160 			break;
161 		}
162 		};
163 
164 		return true;
165 	} else if (type == VIRTIO_PCI_O_CONFIG) {
166 		vtrans->virtio_ops->set_config(kvm, vpci->dev, *(u8 *)data, config_offset);
167 
168 		return true;
169 	}
170 
171 	return false;
172 }
173 
174 static bool virtio_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
175 {
176 	unsigned long offset;
177 	bool ret = true;
178 	struct virtio_trans *vtrans;
179 	struct virtio_pci *vpci;
180 	u32 val;
181 
182 	vtrans = ioport->priv;
183 	vpci = vtrans->virtio;
184 	offset = port - vpci->base_addr;
185 
186 	switch (offset) {
187 	case VIRTIO_PCI_GUEST_FEATURES:
188 		val = ioport__read32(data);
189 		vtrans->virtio_ops->set_guest_features(kvm, vpci->dev, val);
190 		break;
191 	case VIRTIO_PCI_QUEUE_PFN:
192 		val = ioport__read32(data);
193 		virtio_pci__init_ioeventfd(kvm, vtrans, vpci->queue_selector);
194 		vtrans->virtio_ops->init_vq(kvm, vpci->dev, vpci->queue_selector, val);
195 		break;
196 	case VIRTIO_PCI_QUEUE_SEL:
197 		vpci->queue_selector	= ioport__read16(data);
198 		break;
199 	case VIRTIO_PCI_QUEUE_NOTIFY:
200 		val			= ioport__read16(data);
201 		vtrans->virtio_ops->notify_vq(kvm, vpci->dev, val);
202 		break;
203 	case VIRTIO_PCI_STATUS:
204 		vpci->status		= ioport__read8(data);
205 		break;
206 	default:
207 		ret = virtio_pci__specific_io_out(kvm, vtrans, port, data, size, offset);
208 		break;
209 	};
210 
211 	return ret;
212 }
213 
214 static struct ioport_operations virtio_pci__io_ops = {
215 	.io_in	= virtio_pci__io_in,
216 	.io_out	= virtio_pci__io_out,
217 };
218 
219 static void callback_mmio_table(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
220 {
221 	struct virtio_pci *vpci = ptr;
222 	void *table = &vpci->msix_table;
223 
224 	if (is_write)
225 		memcpy(table + addr - vpci->msix_io_block, data, len);
226 	else
227 		memcpy(data, table + addr - vpci->msix_io_block, len);
228 }
229 
230 static void callback_mmio_pba(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
231 {
232 	struct virtio_pci *vpci = ptr;
233 	void *pba = &vpci->msix_pba;
234 
235 	if (is_write)
236 		memcpy(pba + addr - vpci->msix_pba_block, data, len);
237 	else
238 		memcpy(data, pba + addr - vpci->msix_pba_block, len);
239 }
240 
241 int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
242 {
243 	struct virtio_pci *vpci = vtrans->virtio;
244 	int tbl = vpci->vq_vector[vq];
245 
246 	if (virtio_pci__msix_enabled(vpci)) {
247 		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
248 			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
249 
250 			vpci->msix_pba |= 1 << tbl;
251 			return 0;
252 		}
253 
254 		kvm__irq_trigger(kvm, vpci->gsis[vq]);
255 	} else {
256 		vpci->isr = VIRTIO_IRQ_HIGH;
257 		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
258 	}
259 	return 0;
260 }
261 
262 int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans)
263 {
264 	struct virtio_pci *vpci = vtrans->virtio;
265 	int tbl = vpci->config_vector;
266 
267 	if (virtio_pci__msix_enabled(vpci)) {
268 		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
269 			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
270 
271 			vpci->msix_pba |= 1 << tbl;
272 			return 0;
273 		}
274 
275 		kvm__irq_trigger(kvm, vpci->config_gsi);
276 	} else {
277 		vpci->isr = VIRTIO_PCI_ISR_CONFIG;
278 		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
279 	}
280 
281 	return 0;
282 }
283 
284 int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
285 			int device_id, int subsys_id, int class)
286 {
287 	struct virtio_pci *vpci = vtrans->virtio;
288 	u8 pin, line, ndev;
289 
290 	vpci->dev = dev;
291 	vpci->msix_io_block = pci_get_io_space_block(PCI_IO_SIZE);
292 	vpci->msix_pba_block = pci_get_io_space_block(PCI_IO_SIZE);
293 
294 	vpci->base_addr = ioport__register(IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vtrans);
295 	kvm__register_mmio(kvm, vpci->msix_io_block, 0x100, callback_mmio_table, vpci);
296 	kvm__register_mmio(kvm, vpci->msix_pba_block, 0x100, callback_mmio_pba, vpci);
297 
298 	vpci->pci_hdr = (struct pci_device_header) {
299 		.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
300 		.device_id		= device_id,
301 		.header_type		= PCI_HEADER_TYPE_NORMAL,
302 		.revision_id		= 0,
303 		.class			= class,
304 		.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
305 		.subsys_id		= subsys_id,
306 		.bar[0]			= vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO,
307 		.bar[1]			= vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
308 					| PCI_BASE_ADDRESS_MEM_TYPE_64,
309 		.bar[3]			= vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
310 					| PCI_BASE_ADDRESS_MEM_TYPE_64,
311 		.status			= PCI_STATUS_CAP_LIST,
312 		.capabilities		= (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
313 	};
314 
315 	vpci->pci_hdr.msix.cap = PCI_CAP_ID_MSIX;
316 	vpci->pci_hdr.msix.next = 0;
317 	/*
318 	 * We at most have VIRTIO_PCI_MAX_VQ entries for virt queue,
319 	 * VIRTIO_PCI_MAX_CONFIG entries for config.
320 	 *
321 	 * To quote the PCI spec:
322 	 *
323 	 * System software reads this field to determine the
324 	 * MSI-X Table Size N, which is encoded as N-1.
325 	 * For example, a returned value of "00000000011"
326 	 * indicates a table size of 4.
327 	 */
328 	vpci->pci_hdr.msix.ctrl = (VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
329 
330 	/*
331 	 * Both table and PBA could be mapped on the same BAR, but for now
332 	 * we're not in short of BARs
333 	 */
334 	vpci->pci_hdr.msix.table_offset = 1; /* Use BAR 1 */
335 	vpci->pci_hdr.msix.pba_offset = 3; /* Use BAR 3 */
336 	vpci->config_vector = 0;
337 
338 	if (irq__register_device(subsys_id, &ndev, &pin, &line) < 0)
339 		return -1;
340 
341 	vpci->pci_hdr.irq_pin	= pin;
342 	vpci->pci_hdr.irq_line	= line;
343 	pci__register(&vpci->pci_hdr, ndev);
344 
345 	return 0;
346 }
347