xref: /linux/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h (revision 3152e7f457dece42b13423c45a371ee686074fac)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DEVICE_H
3 #define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DEVICE_H
4 
5 #include <fcntl.h>
6 #include <linux/vfio.h>
7 #include <linux/pci_regs.h>
8 
9 #include <libvfio/assert.h>
10 #include <libvfio/iommu.h>
11 #include <libvfio/vfio_pci_driver.h>
12 
13 struct vfio_pci_bar {
14 	struct vfio_region_info info;
15 	void *vaddr;
16 };
17 
18 struct vfio_pci_device {
19 	const char *bdf;
20 	int fd;
21 	int group_fd;
22 
23 	struct iommu *iommu;
24 
25 	struct vfio_device_info info;
26 	struct vfio_region_info config_space;
27 	struct vfio_pci_bar bars[PCI_STD_NUM_BARS];
28 
29 	struct vfio_irq_info msi_info;
30 	struct vfio_irq_info msix_info;
31 
32 	/* eventfds for MSI and MSI-x interrupts */
33 	int msi_eventfds[PCI_MSIX_FLAGS_QSIZE + 1];
34 
35 	struct vfio_pci_driver driver;
36 };
37 
38 #define dev_info(_dev, _fmt, ...) printf("%s: " _fmt, (_dev)->bdf, ##__VA_ARGS__)
39 #define dev_err(_dev, _fmt, ...) fprintf(stderr, "%s: " _fmt, (_dev)->bdf, ##__VA_ARGS__)
40 
41 struct vfio_pci_device *vfio_pci_device_alloc(const char *bdf, struct iommu *iommu);
42 void vfio_pci_device_free(struct vfio_pci_device *device);
43 struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu);
44 void vfio_pci_device_cleanup(struct vfio_pci_device *device);
45 
46 void vfio_pci_device_reset(struct vfio_pci_device *device);
47 
48 void vfio_pci_config_access(struct vfio_pci_device *device, bool write,
49 			    size_t config, size_t size, void *data);
50 
51 #define vfio_pci_config_read(_device, _offset, _type) ({			    \
52 	_type __data;								    \
53 	vfio_pci_config_access((_device), false, _offset, sizeof(__data), &__data); \
54 	__data;									    \
55 })
56 
57 #define vfio_pci_config_readb(_d, _o) vfio_pci_config_read(_d, _o, u8)
58 #define vfio_pci_config_readw(_d, _o) vfio_pci_config_read(_d, _o, u16)
59 #define vfio_pci_config_readl(_d, _o) vfio_pci_config_read(_d, _o, u32)
60 
61 #define vfio_pci_config_write(_device, _offset, _value, _type) do {		  \
62 	_type __data = (_value);						  \
63 	vfio_pci_config_access((_device), true, _offset, sizeof(_type), &__data); \
64 } while (0)
65 
66 #define vfio_pci_config_writeb(_d, _o, _v) vfio_pci_config_write(_d, _o, _v, u8)
67 #define vfio_pci_config_writew(_d, _o, _v) vfio_pci_config_write(_d, _o, _v, u16)
68 #define vfio_pci_config_writel(_d, _o, _v) vfio_pci_config_write(_d, _o, _v, u32)
69 
70 void vfio_pci_irq_enable(struct vfio_pci_device *device, u32 index,
71 			 u32 vector, int count);
72 void vfio_pci_irq_disable(struct vfio_pci_device *device, u32 index);
73 void vfio_pci_irq_trigger(struct vfio_pci_device *device, u32 index, u32 vector);
74 
75 static inline void fcntl_set_nonblock(int fd)
76 {
77 	int r;
78 
79 	r = fcntl(fd, F_GETFL, 0);
80 	VFIO_ASSERT_NE(r, -1, "F_GETFL failed for fd %d\n", fd);
81 
82 	r = fcntl(fd, F_SETFL, r | O_NONBLOCK);
83 	VFIO_ASSERT_NE(r, -1, "F_SETFL O_NONBLOCK failed for fd %d\n", fd);
84 }
85 
86 static inline void vfio_pci_msi_enable(struct vfio_pci_device *device,
87 				       u32 vector, int count)
88 {
89 	vfio_pci_irq_enable(device, VFIO_PCI_MSI_IRQ_INDEX, vector, count);
90 }
91 
92 static inline void vfio_pci_msi_disable(struct vfio_pci_device *device)
93 {
94 	vfio_pci_irq_disable(device, VFIO_PCI_MSI_IRQ_INDEX);
95 }
96 
97 static inline void vfio_pci_msix_enable(struct vfio_pci_device *device,
98 					u32 vector, int count)
99 {
100 	vfio_pci_irq_enable(device, VFIO_PCI_MSIX_IRQ_INDEX, vector, count);
101 }
102 
103 static inline void vfio_pci_msix_disable(struct vfio_pci_device *device)
104 {
105 	vfio_pci_irq_disable(device, VFIO_PCI_MSIX_IRQ_INDEX);
106 }
107 
108 static inline int __to_iova(struct vfio_pci_device *device, void *vaddr, iova_t *iova)
109 {
110 	return __iommu_hva2iova(device->iommu, vaddr, iova);
111 }
112 
113 static inline iova_t to_iova(struct vfio_pci_device *device, void *vaddr)
114 {
115 	return iommu_hva2iova(device->iommu, vaddr);
116 }
117 
118 static inline bool vfio_pci_device_match(struct vfio_pci_device *device,
119 					 u16 vendor_id, u16 device_id)
120 {
121 	return (vendor_id == vfio_pci_config_readw(device, PCI_VENDOR_ID)) &&
122 		(device_id == vfio_pci_config_readw(device, PCI_DEVICE_ID));
123 }
124 
125 const char *vfio_pci_get_cdev_path(const char *bdf);
126 
127 void vfio_pci_group_setup(struct vfio_pci_device *device, const char *bdf);
128 void __vfio_pci_group_get_device_fd(struct vfio_pci_device *device,
129 				    const char *bdf, const char *vf_token);
130 void vfio_container_set_iommu(struct vfio_pci_device *device);
131 void vfio_pci_cdev_open(struct vfio_pci_device *device, const char *bdf);
132 int __vfio_device_bind_iommufd(int device_fd, int iommufd, const char *vf_token);
133 
134 void vfio_device_set_vf_token(int fd, const char *vf_token);
135 
136 #endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DEVICE_H */
137