xref: /kvmtool/virtio/pci.c (revision 263b80e8e9b8c42060916720fe046de6ddc4c391)
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 							0, &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__write32(data, val);
119 		break;
120 		break;
121 	case VIRTIO_PCI_STATUS:
122 		ioport__write8(data, vpci->status);
123 		break;
124 	case VIRTIO_PCI_ISR:
125 		ioport__write8(data, vpci->isr);
126 		kvm__irq_line(kvm, vpci->pci_hdr.irq_line, VIRTIO_IRQ_LOW);
127 		vpci->isr = VIRTIO_IRQ_LOW;
128 		break;
129 	default:
130 		ret = virtio_pci__specific_io_in(kvm, vtrans, port, data, size, offset);
131 		break;
132 	};
133 
134 	return ret;
135 }
136 
137 static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
138 					void *data, int size, int offset)
139 {
140 	struct virtio_pci *vpci = vtrans->virtio;
141 	u32 config_offset, gsi, vec;
142 	int type = virtio__get_dev_specific_field(offset - 20, virtio_pci__msix_enabled(vpci),
143 							0, &config_offset);
144 	if (type == VIRTIO_PCI_O_MSIX) {
145 		switch (offset) {
146 		case VIRTIO_MSI_CONFIG_VECTOR:
147 			vec = vpci->config_vector = ioport__read16(data);
148 
149 			gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg);
150 
151 			vpci->config_gsi = gsi;
152 			break;
153 		case VIRTIO_MSI_QUEUE_VECTOR: {
154 			vec = vpci->vq_vector[vpci->queue_selector] = ioport__read16(data);
155 
156 			gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg);
157 			vpci->gsis[vpci->queue_selector] = gsi;
158 			if (vtrans->virtio_ops->notify_vq_gsi)
159 				vtrans->virtio_ops->notify_vq_gsi(kvm, vpci->dev,
160 							vpci->queue_selector, gsi);
161 			break;
162 		}
163 		};
164 
165 		return true;
166 	} else if (type == VIRTIO_PCI_O_CONFIG) {
167 		vtrans->virtio_ops->set_config(kvm, vpci->dev, *(u8 *)data, config_offset);
168 
169 		return true;
170 	}
171 
172 	return false;
173 }
174 
175 static bool virtio_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
176 {
177 	unsigned long offset;
178 	bool ret = true;
179 	struct virtio_trans *vtrans;
180 	struct virtio_pci *vpci;
181 	u32 val;
182 
183 	vtrans = ioport->priv;
184 	vpci = vtrans->virtio;
185 	offset = port - vpci->base_addr;
186 
187 	switch (offset) {
188 	case VIRTIO_PCI_GUEST_FEATURES:
189 		val = ioport__read32(data);
190 		vtrans->virtio_ops->set_guest_features(kvm, vpci->dev, val);
191 		break;
192 	case VIRTIO_PCI_QUEUE_PFN:
193 		val = ioport__read32(data);
194 		virtio_pci__init_ioeventfd(kvm, vtrans, vpci->queue_selector);
195 		vtrans->virtio_ops->init_vq(kvm, vpci->dev, vpci->queue_selector, val);
196 		break;
197 	case VIRTIO_PCI_QUEUE_SEL:
198 		vpci->queue_selector	= ioport__read16(data);
199 		break;
200 	case VIRTIO_PCI_QUEUE_NOTIFY:
201 		val			= ioport__read16(data);
202 		vtrans->virtio_ops->notify_vq(kvm, vpci->dev, val);
203 		break;
204 	case VIRTIO_PCI_STATUS:
205 		vpci->status		= ioport__read8(data);
206 		break;
207 	default:
208 		ret = virtio_pci__specific_io_out(kvm, vtrans, port, data, size, offset);
209 		break;
210 	};
211 
212 	return ret;
213 }
214 
215 static struct ioport_operations virtio_pci__io_ops = {
216 	.io_in	= virtio_pci__io_in,
217 	.io_out	= virtio_pci__io_out,
218 };
219 
220 static void callback_mmio_table(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
221 {
222 	struct virtio_pci *vpci = ptr;
223 	void *table = &vpci->msix_table;
224 
225 	if (is_write)
226 		memcpy(table + addr - vpci->msix_io_block, data, len);
227 	else
228 		memcpy(data, table + addr - vpci->msix_io_block, len);
229 }
230 
231 static void callback_mmio_pba(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
232 {
233 	struct virtio_pci *vpci = ptr;
234 	void *pba = &vpci->msix_pba;
235 
236 	if (is_write)
237 		memcpy(pba + addr - vpci->msix_pba_block, data, len);
238 	else
239 		memcpy(data, pba + addr - vpci->msix_pba_block, len);
240 }
241 
242 int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
243 {
244 	struct virtio_pci *vpci = vtrans->virtio;
245 	int tbl = vpci->vq_vector[vq];
246 
247 	if (virtio_pci__msix_enabled(vpci)) {
248 		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
249 			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
250 
251 			vpci->msix_pba |= 1 << tbl;
252 			return 0;
253 		}
254 
255 		kvm__irq_trigger(kvm, vpci->gsis[vq]);
256 	} else {
257 		vpci->isr = VIRTIO_IRQ_HIGH;
258 		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
259 	}
260 	return 0;
261 }
262 
263 int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans)
264 {
265 	struct virtio_pci *vpci = vtrans->virtio;
266 	int tbl = vpci->config_vector;
267 
268 	if (virtio_pci__msix_enabled(vpci)) {
269 		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
270 			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
271 
272 			vpci->msix_pba |= 1 << tbl;
273 			return 0;
274 		}
275 
276 		kvm__irq_trigger(kvm, vpci->config_gsi);
277 	} else {
278 		vpci->isr = VIRTIO_PCI_ISR_CONFIG;
279 		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
280 	}
281 
282 	return 0;
283 }
284 
285 int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
286 			int device_id, int subsys_id, int class)
287 {
288 	struct virtio_pci *vpci = vtrans->virtio;
289 	u8 pin, line, ndev;
290 
291 	vpci->dev = dev;
292 	vpci->msix_io_block = pci_get_io_space_block(PCI_IO_SIZE);
293 	vpci->msix_pba_block = pci_get_io_space_block(PCI_IO_SIZE);
294 
295 	vpci->base_addr = ioport__register(IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vtrans);
296 	kvm__register_mmio(kvm, vpci->msix_io_block, 0x100, callback_mmio_table, vpci);
297 	kvm__register_mmio(kvm, vpci->msix_pba_block, 0x100, callback_mmio_pba, vpci);
298 
299 	vpci->pci_hdr = (struct pci_device_header) {
300 		.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
301 		.device_id		= device_id,
302 		.header_type		= PCI_HEADER_TYPE_NORMAL,
303 		.revision_id		= 0,
304 		.class			= class,
305 		.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
306 		.subsys_id		= subsys_id,
307 		.bar[0]			= vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO,
308 		.bar[1]			= vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
309 					| PCI_BASE_ADDRESS_MEM_TYPE_64,
310 		.bar[3]			= vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
311 					| PCI_BASE_ADDRESS_MEM_TYPE_64,
312 		.status			= PCI_STATUS_CAP_LIST,
313 		.capabilities		= (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
314 	};
315 
316 	vpci->pci_hdr.msix.cap = PCI_CAP_ID_MSIX;
317 	vpci->pci_hdr.msix.next = 0;
318 	/*
319 	 * We at most have VIRTIO_PCI_MAX_VQ entries for virt queue,
320 	 * VIRTIO_PCI_MAX_CONFIG entries for config.
321 	 *
322 	 * To quote the PCI spec:
323 	 *
324 	 * System software reads this field to determine the
325 	 * MSI-X Table Size N, which is encoded as N-1.
326 	 * For example, a returned value of "00000000011"
327 	 * indicates a table size of 4.
328 	 */
329 	vpci->pci_hdr.msix.ctrl = (VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
330 
331 	/*
332 	 * Both table and PBA could be mapped on the same BAR, but for now
333 	 * we're not in short of BARs
334 	 */
335 	vpci->pci_hdr.msix.table_offset = 1; /* Use BAR 1 */
336 	vpci->pci_hdr.msix.pba_offset = 3; /* Use BAR 3 */
337 	vpci->config_vector = 0;
338 
339 	if (irq__register_device(subsys_id, &ndev, &pin, &line) < 0)
340 		return -1;
341 
342 	vpci->pci_hdr.irq_pin	= pin;
343 	vpci->pci_hdr.irq_line	= line;
344 	pci__register(&vpci->pci_hdr, ndev);
345 
346 	return 0;
347 }
348