summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_driver.h
blob: e5ada209b1d102f6aafd4a3cccd103d31439a042 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H
#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H

#include <libvfio/iommu.h>

struct vfio_pci_device;

struct vfio_pci_driver_ops {
	const char *name;

	/**
	 * @probe() - Check if the driver supports the given device.
	 *
	 * Return: 0 on success, non-0 on failure.
	 */
	int (*probe)(struct vfio_pci_device *device);

	/**
	 * @init() - Initialize the driver for @device.
	 *
	 * Must be called after device->driver.region has been initialized.
	 */
	void (*init)(struct vfio_pci_device *device);

	/**
	 * remove() - Deinitialize the driver for @device.
	 */
	void (*remove)(struct vfio_pci_device *device);

	/**
	 * memcpy_start() - Kick off @count repeated memcpy operations from
	 * [@src, @src + @size) to [@dst, @dst + @size).
	 *
	 * Guarantees:
	 *  - The device will attempt DMA reads on [src, src + size).
	 *  - The device will attempt DMA writes on [dst, dst + size).
	 *  - The device will not generate any interrupts.
	 *
	 * memcpy_start() returns immediately, it does not wait for the
	 * copies to complete.
	 */
	void (*memcpy_start)(struct vfio_pci_device *device,
			     iova_t src, iova_t dst, u64 size, u64 count);

	/**
	 * memcpy_wait() - Wait until the memcpy operations started by
	 * memcpy_start() have finished.
	 *
	 * Guarantees:
	 *  - All in-flight DMAs initiated by memcpy_start() are fully complete
	 *    before memcpy_wait() returns.
	 *
	 * Returns non-0 if the driver detects that an error occurred during the
	 * memcpy, 0 otherwise.
	 */
	int (*memcpy_wait)(struct vfio_pci_device *device);

	/**
	 * send_msi() - Make the device send the MSI device->driver.msi.
	 *
	 * Guarantees:
	 *  - The device will send the MSI once.
	 */
	void (*send_msi)(struct vfio_pci_device *device);
};

struct vfio_pci_driver {
	const struct vfio_pci_driver_ops *ops;
	bool initialized;
	bool memcpy_in_progress;

	/* Region to be used by the driver (e.g. for in-memory descriptors) */
	struct dma_region region;

	/* The maximum size that can be passed to memcpy_start(). */
	u64 max_memcpy_size;

	/* The maximum count that can be passed to memcpy_start(). */
	u64 max_memcpy_count;

	/* The MSI vector the device will signal in ops->send_msi(). */
	int msi;
};

void vfio_pci_driver_probe(struct vfio_pci_device *device);
void vfio_pci_driver_init(struct vfio_pci_device *device);
void vfio_pci_driver_remove(struct vfio_pci_device *device);
int vfio_pci_driver_memcpy(struct vfio_pci_device *device,
			   iova_t src, iova_t dst, u64 size);
void vfio_pci_driver_memcpy_start(struct vfio_pci_device *device,
				  iova_t src, iova_t dst, u64 size,
				  u64 count);
int vfio_pci_driver_memcpy_wait(struct vfio_pci_device *device);
void vfio_pci_driver_send_msi(struct vfio_pci_device *device);

#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H */