1 #ifndef KVM__VIRTIO_PCI_H
2 #define KVM__VIRTIO_PCI_H
3
4 #include "kvm/devices.h"
5 #include "kvm/pci.h"
6 #include "kvm/virtio.h"
7
8 #include <stdbool.h>
9 #include <linux/byteorder.h>
10 #include <linux/types.h>
11
12 #define VIRTIO_PCI_MAX_VQ 32
13 #define VIRTIO_PCI_MAX_CONFIG 1
14
15 struct kvm;
16 struct kvm_cpu;
17
18 struct virtio_pci_ioevent_param {
19 struct virtio_device *vdev;
20 u32 vq;
21 };
22
23 #define ALIGN_UP(x, s) ALIGN((x) + (s) - 1, (s))
24 #define VIRTIO_NR_MSIX (VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG)
25 #define VIRTIO_MSIX_TABLE_SIZE (VIRTIO_NR_MSIX * 16)
26 #define VIRTIO_MSIX_PBA_SIZE (ALIGN_UP(VIRTIO_MSIX_TABLE_SIZE, 64) / 8)
27 #define VIRTIO_MSIX_BAR_SIZE (1UL << fls_long(VIRTIO_MSIX_TABLE_SIZE + \
28 VIRTIO_MSIX_PBA_SIZE))
29
30 struct virtio_pci {
31 struct pci_device_header pci_hdr;
32 struct device_header dev_hdr;
33 void *dev;
34 struct kvm *kvm;
35
36 u32 doorbell_offset;
37 bool signal_msi;
38 u8 status;
39 u8 isr;
40 u32 device_features_sel;
41 u32 driver_features_sel;
42
43 /*
44 * We cannot rely on the INTERRUPT_LINE byte in the config space once
45 * we have run guest code, as the OS is allowed to use that field
46 * as a scratch pad to communicate between driver and PCI layer.
47 * So store our legacy interrupt line number in here for internal use.
48 */
49 u8 legacy_irq_line;
50
51 /* MSI-X */
52 u16 config_vector;
53 u32 config_gsi;
54 u16 vq_vector[VIRTIO_PCI_MAX_VQ];
55 u32 gsis[VIRTIO_PCI_MAX_VQ];
56 u64 msix_pba;
57 struct msix_table msix_table[VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG];
58
59 /* virtio queue */
60 u16 queue_selector;
61 struct virtio_pci_ioevent_param ioeventfds[VIRTIO_PCI_MAX_VQ];
62 };
63
64 int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_device *vdev, u32 vq);
65 int virtio_pci__signal_config(struct kvm *kvm, struct virtio_device *vdev);
66 int virtio_pci__exit(struct kvm *kvm, struct virtio_device *vdev);
67 int virtio_pci__reset(struct kvm *kvm, struct virtio_device *vdev);
68 int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
69 int device_id, int subsys_id, int class);
70 int virtio_pci_modern_init(struct virtio_device *vdev);
71
virtio_pci__msix_enabled(struct virtio_pci * vpci)72 static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
73 {
74 return vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE);
75 }
76
virtio_pci__port_addr(struct virtio_pci * vpci)77 static inline u16 virtio_pci__port_addr(struct virtio_pci *vpci)
78 {
79 return pci__bar_address(&vpci->pci_hdr, 0);
80 }
81
virtio_pci__mmio_addr(struct virtio_pci * vpci)82 static inline u32 virtio_pci__mmio_addr(struct virtio_pci *vpci)
83 {
84 return pci__bar_address(&vpci->pci_hdr, 1);
85 }
86
virtio_pci__msix_io_addr(struct virtio_pci * vpci)87 static inline u32 virtio_pci__msix_io_addr(struct virtio_pci *vpci)
88 {
89 return pci__bar_address(&vpci->pci_hdr, 2);
90 }
91
92 int virtio_pci__add_msix_route(struct virtio_pci *vpci, u32 vec);
93 int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vdev,
94 u32 vq);
95 int virtio_pci_init_vq(struct kvm *kvm, struct virtio_device *vdev, int vq);
96 void virtio_pci_exit_vq(struct kvm *kvm, struct virtio_device *vdev, int vq);
97
98 void virtio_pci_legacy__io_mmio_callback(struct kvm_cpu *vcpu, u64 addr, u8 *data,
99 u32 len, u8 is_write, void *ptr);
100 void virtio_pci_modern__io_mmio_callback(struct kvm_cpu *vcpu, u64 addr, u8 *data,
101 u32 len, u8 is_write, void *ptr);
102
103 #endif
104