History

Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost

Pull virtio updates from Michael Tsirkin: - Some bug fixes - The new vdpa subsystem with two first drivers * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: virtio-balloon: Revert "virtio-balloon: Switch back to OOM handler for VIRTIO_BALLOON_F_DEFLATE_ON_OOM" vdpa: move to drivers/vdpa virtio: Intel IFC VF driver for VDPA vdpasim: vDPA device simulator vhost: introduce vDPA-based backend virtio: introduce a vDPA based transport vDPA: introduce vDPA bus vringh: IOTLB support vhost: factor out IOTLB vhost: allow per device message handler vhost: refine vhost and vringh kconfig virtio-balloon: Switch back to OOM handler for VIRTIO_BALLOON_F_DEFLATE_ON_OOM virtio-net: Introduce hash report feature virtio-net: Introduce RSS receive steering feature virtio-net: Introduce extended RSC feature tools/virtio: option to build an out of tree module

Linus Torvalds committed 6 years ago

Commit 9bb71522 parents ae46d2a 835a6a640 files · +4310 −249Browse files

Showing the changes to include/linux (3 of 40 files). Show all

Unified · Split

3 files
  1. include/linux/vdpa.h +253 −0
  2. include/linux/vhost_iotlb.h +47 −0
  3. include/linux/vringh.h +36 −0
include/linux/vdpa.h+253−0
@@ -0,0 +1,253 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef _LINUX_VDPA_H
3+#define _LINUX_VDPA_H
4+
5+#include <linux/kernel.h>
6+#include <linux/device.h>
7+#include <linux/interrupt.h>
8+#include <linux/vhost_iotlb.h>
9+
10+/**
11+ * vDPA callback definition.
12+ * @callback: interrupt callback function
13+ * @private: the data passed to the callback function
14+ */
15+struct vdpa_callback {
16+ irqreturn_t (*callback)(void *data);
17+ void *private;
18+};
19+
20+/**
21+ * vDPA device - representation of a vDPA device
22+ * @dev: underlying device
23+ * @dma_dev: the actual device that is performing DMA
24+ * @config: the configuration ops for this device.
25+ * @index: device index
26+ */
27+struct vdpa_device {
28+ struct device dev;
29+ struct device *dma_dev;
30+ const struct vdpa_config_ops *config;
31+ unsigned int index;
32+};
33+
34+/**
35+ * vDPA_config_ops - operations for configuring a vDPA device.
36+ * Note: vDPA device drivers are required to implement all of the
37+ * operations unless it is mentioned to be optional in the following
38+ * list.
39+ *
40+ * @set_vq_address: Set the address of virtqueue
41+ * @vdev: vdpa device
42+ * @idx: virtqueue index
43+ * @desc_area: address of desc area
44+ * @driver_area: address of driver area
45+ * @device_area: address of device area
46+ * Returns integer: success (0) or error (< 0)
47+ * @set_vq_num: Set the size of virtqueue
48+ * @vdev: vdpa device
49+ * @idx: virtqueue index
50+ * @num: the size of virtqueue
51+ * @kick_vq: Kick the virtqueue
52+ * @vdev: vdpa device
53+ * @idx: virtqueue index
54+ * @set_vq_cb: Set the interrupt callback function for
55+ * a virtqueue
56+ * @vdev: vdpa device
57+ * @idx: virtqueue index
58+ * @cb: virtio-vdev interrupt callback structure
59+ * @set_vq_ready: Set ready status for a virtqueue
60+ * @vdev: vdpa device
61+ * @idx: virtqueue index
62+ * @ready: ready (true) not ready(false)
63+ * @get_vq_ready: Get ready status for a virtqueue
64+ * @vdev: vdpa device
65+ * @idx: virtqueue index
66+ * Returns boolean: ready (true) or not (false)
67+ * @set_vq_state: Set the state for a virtqueue
68+ * @vdev: vdpa device
69+ * @idx: virtqueue index
70+ * @state: virtqueue state (last_avail_idx)
71+ * Returns integer: success (0) or error (< 0)
72+ * @get_vq_state: Get the state for a virtqueue
73+ * @vdev: vdpa device
74+ * @idx: virtqueue index
75+ * Returns virtqueue state (last_avail_idx)
76+ * @get_vq_align: Get the virtqueue align requirement
77+ * for the device
78+ * @vdev: vdpa device
79+ * Returns virtqueue algin requirement
80+ * @get_features: Get virtio features supported by the device
81+ * @vdev: vdpa device
82+ * Returns the virtio features support by the
83+ * device
84+ * @set_features: Set virtio features supported by the driver
85+ * @vdev: vdpa device
86+ * @features: feature support by the driver
87+ * Returns integer: success (0) or error (< 0)
88+ * @set_config_cb: Set the config interrupt callback
89+ * @vdev: vdpa device
90+ * @cb: virtio-vdev interrupt callback structure
91+ * @get_vq_num_max: Get the max size of virtqueue
92+ * @vdev: vdpa device
93+ * Returns u16: max size of virtqueue
94+ * @get_device_id: Get virtio device id
95+ * @vdev: vdpa device
96+ * Returns u32: virtio device id
97+ * @get_vendor_id: Get id for the vendor that provides this device
98+ * @vdev: vdpa device
99+ * Returns u32: virtio vendor id
100+ * @get_status: Get the device status
101+ * @vdev: vdpa device
102+ * Returns u8: virtio device status
103+ * @set_status: Set the device status
104+ * @vdev: vdpa device
105+ * @status: virtio device status
106+ * @get_config: Read from device specific configuration space
107+ * @vdev: vdpa device
108+ * @offset: offset from the beginning of
109+ * configuration space
110+ * @buf: buffer used to read to
111+ * @len: the length to read from
112+ * configuration space
113+ * @set_config: Write to device specific configuration space
114+ * @vdev: vdpa device
115+ * @offset: offset from the beginning of
116+ * configuration space
117+ * @buf: buffer used to write from
118+ * @len: the length to write to
119+ * configuration space
120+ * @get_generation: Get device config generation (optional)
121+ * @vdev: vdpa device
122+ * Returns u32: device generation
123+ * @set_map: Set device memory mapping (optional)
124+ * Needed for device that using device
125+ * specific DMA translation (on-chip IOMMU)
126+ * @vdev: vdpa device
127+ * @iotlb: vhost memory mapping to be
128+ * used by the vDPA
129+ * Returns integer: success (0) or error (< 0)
130+ * @dma_map: Map an area of PA to IOVA (optional)
131+ * Needed for device that using device
132+ * specific DMA translation (on-chip IOMMU)
133+ * and preferring incremental map.
134+ * @vdev: vdpa device
135+ * @iova: iova to be mapped
136+ * @size: size of the area
137+ * @pa: physical address for the map
138+ * @perm: device access permission (VHOST_MAP_XX)
139+ * Returns integer: success (0) or error (< 0)
140+ * @dma_unmap: Unmap an area of IOVA (optional but
141+ * must be implemented with dma_map)
142+ * Needed for device that using device
143+ * specific DMA translation (on-chip IOMMU)
144+ * and preferring incremental unmap.
145+ * @vdev: vdpa device
146+ * @iova: iova to be unmapped
147+ * @size: size of the area
148+ * Returns integer: success (0) or error (< 0)
149+ * @free: Free resources that belongs to vDPA (optional)
150+ * @vdev: vdpa device
151+ */
152+struct vdpa_config_ops {
153+ /* Virtqueue ops */
154+ int (*set_vq_address)(struct vdpa_device *vdev,
155+ u16 idx, u64 desc_area, u64 driver_area,
156+ u64 device_area);
157+ void (*set_vq_num)(struct vdpa_device *vdev, u16 idx, u32 num);
158+ void (*kick_vq)(struct vdpa_device *vdev, u16 idx);
159+ void (*set_vq_cb)(struct vdpa_device *vdev, u16 idx,
160+ struct vdpa_callback *cb);
161+ void (*set_vq_ready)(struct vdpa_device *vdev, u16 idx, bool ready);
162+ bool (*get_vq_ready)(struct vdpa_device *vdev, u16 idx);
163+ int (*set_vq_state)(struct vdpa_device *vdev, u16 idx, u64 state);
164+ u64 (*get_vq_state)(struct vdpa_device *vdev, u16 idx);
165+
166+ /* Device ops */
167+ u16 (*get_vq_align)(struct vdpa_device *vdev);
168+ u64 (*get_features)(struct vdpa_device *vdev);
169+ int (*set_features)(struct vdpa_device *vdev, u64 features);
170+ void (*set_config_cb)(struct vdpa_device *vdev,
171+ struct vdpa_callback *cb);
172+ u16 (*get_vq_num_max)(struct vdpa_device *vdev);
173+ u32 (*get_device_id)(struct vdpa_device *vdev);
174+ u32 (*get_vendor_id)(struct vdpa_device *vdev);
175+ u8 (*get_status)(struct vdpa_device *vdev);
176+ void (*set_status)(struct vdpa_device *vdev, u8 status);
177+ void (*get_config)(struct vdpa_device *vdev, unsigned int offset,
178+ void *buf, unsigned int len);
179+ void (*set_config)(struct vdpa_device *vdev, unsigned int offset,
180+ const void *buf, unsigned int len);
181+ u32 (*get_generation)(struct vdpa_device *vdev);
182+
183+ /* DMA ops */
184+ int (*set_map)(struct vdpa_device *vdev, struct vhost_iotlb *iotlb);
185+ int (*dma_map)(struct vdpa_device *vdev, u64 iova, u64 size,
186+ u64 pa, u32 perm);
187+ int (*dma_unmap)(struct vdpa_device *vdev, u64 iova, u64 size);
188+
189+ /* Free device resources */
190+ void (*free)(struct vdpa_device *vdev);
191+};
192+
193+struct vdpa_device *__vdpa_alloc_device(struct device *parent,
194+ const struct vdpa_config_ops *config,
195+ size_t size);
196+
197+#define vdpa_alloc_device(dev_struct, member, parent, config) \
198+ container_of(__vdpa_alloc_device( \
199+ parent, config, \
200+ sizeof(dev_struct) + \
201+ BUILD_BUG_ON_ZERO(offsetof( \
202+ dev_struct, member))), \
203+ dev_struct, member)
204+
205+int vdpa_register_device(struct vdpa_device *vdev);
206+void vdpa_unregister_device(struct vdpa_device *vdev);
207+
208+/**
209+ * vdpa_driver - operations for a vDPA driver
210+ * @driver: underlying device driver
211+ * @probe: the function to call when a device is found. Returns 0 or -errno.
212+ * @remove: the function to call when a device is removed.
213+ */
214+struct vdpa_driver {
215+ struct device_driver driver;
216+ int (*probe)(struct vdpa_device *vdev);
217+ void (*remove)(struct vdpa_device *vdev);
218+};
219+
220+#define vdpa_register_driver(drv) \
221+ __vdpa_register_driver(drv, THIS_MODULE)
222+int __vdpa_register_driver(struct vdpa_driver *drv, struct module *owner);
223+void vdpa_unregister_driver(struct vdpa_driver *drv);
224+
225+#define module_vdpa_driver(__vdpa_driver) \
226+ module_driver(__vdpa_driver, vdpa_register_driver, \
227+ vdpa_unregister_driver)
228+
229+static inline struct vdpa_driver *drv_to_vdpa(struct device_driver *driver)
230+{
231+ return container_of(driver, struct vdpa_driver, driver);
232+}
233+
234+static inline struct vdpa_device *dev_to_vdpa(struct device *_dev)
235+{
236+ return container_of(_dev, struct vdpa_device, dev);
237+}
238+
239+static inline void *vdpa_get_drvdata(const struct vdpa_device *vdev)
240+{
241+ return dev_get_drvdata(&vdev->dev);
242+}
243+
244+static inline void vdpa_set_drvdata(struct vdpa_device *vdev, void *data)
245+{
246+ dev_set_drvdata(&vdev->dev, data);
247+}
248+
249+static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev)
250+{
251+ return vdev->dma_dev;
252+}
253+#endif /* _LINUX_VDPA_H */
include/linux/vhost_iotlb.h+47−0
@@ -0,0 +1,47 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef _LINUX_VHOST_IOTLB_H
3+#define _LINUX_VHOST_IOTLB_H
4+
5+#include <linux/interval_tree_generic.h>
6+
7+struct vhost_iotlb_map {
8+ struct rb_node rb;
9+ struct list_head link;
10+ u64 start;
11+ u64 last;
12+ u64 size;
13+ u64 addr;
14+#define VHOST_MAP_RO 0x1
15+#define VHOST_MAP_WO 0x2
16+#define VHOST_MAP_RW 0x3
17+ u32 perm;
18+ u32 flags_padding;
19+ u64 __subtree_last;
20+};
21+
22+#define VHOST_IOTLB_FLAG_RETIRE 0x1
23+
24+struct vhost_iotlb {
25+ struct rb_root_cached root;
26+ struct list_head list;
27+ unsigned int limit;
28+ unsigned int nmaps;
29+ unsigned int flags;
30+};
31+
32+int vhost_iotlb_add_range(struct vhost_iotlb *iotlb, u64 start, u64 last,
33+ u64 addr, unsigned int perm);
34+void vhost_iotlb_del_range(struct vhost_iotlb *iotlb, u64 start, u64 last);
35+
36+struct vhost_iotlb *vhost_iotlb_alloc(unsigned int limit, unsigned int flags);
37+void vhost_iotlb_free(struct vhost_iotlb *iotlb);
38+void vhost_iotlb_reset(struct vhost_iotlb *iotlb);
39+
40+struct vhost_iotlb_map *
41+vhost_iotlb_itree_first(struct vhost_iotlb *iotlb, u64 start, u64 last);
42+struct vhost_iotlb_map *
43+vhost_iotlb_itree_next(struct vhost_iotlb_map *map, u64 start, u64 last);
44+
45+void vhost_iotlb_map_free(struct vhost_iotlb *iotlb,
46+ struct vhost_iotlb_map *map);
47+#endif
include/linux/vringh.h+36−0
@@ -14,6 +14,8 @@ · 13 unmodified lines
1414 #include <linux/virtio_byteorder.h>
1515 #include <linux/uio.h>
1616 #include <linux/slab.h>
17+#include <linux/dma-direction.h>
18+#include <linux/vhost_iotlb.h>
1719 #include <asm/barrier.h>
1820
1921 /* virtio_ring with information needed for host access. */
@@ -39,6 +41,9 @@ struct vringh { · 19 unmodified lines
3941 /* The vring (note: it may contain user pointers!) */
4042 struct vring vring;
4143
44+ /* IOTLB for this vring */
45+ struct vhost_iotlb *iotlb;
46+
4247 /* The function to call to notify the guest about added buffers */
4348 void (*notify)(struct vringh *);
4449 };
@@ -248,4 +253,35 @@ static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val) · 203 unmodified lines
248253 {
249254 return __cpu_to_virtio64(vringh_is_little_endian(vrh), val);
250255 }
256+
257+void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb);
258+
259+int vringh_init_iotlb(struct vringh *vrh, u64 features,
260+ unsigned int num, bool weak_barriers,
261+ struct vring_desc *desc,
262+ struct vring_avail *avail,
263+ struct vring_used *used);
264+
265+int vringh_getdesc_iotlb(struct vringh *vrh,
266+ struct vringh_kiov *riov,
267+ struct vringh_kiov *wiov,
268+ u16 *head,
269+ gfp_t gfp);
270+
271+ssize_t vringh_iov_pull_iotlb(struct vringh *vrh,
272+ struct vringh_kiov *riov,
273+ void *dst, size_t len);
274+ssize_t vringh_iov_push_iotlb(struct vringh *vrh,
275+ struct vringh_kiov *wiov,
276+ const void *src, size_t len);
277+
278+void vringh_abandon_iotlb(struct vringh *vrh, unsigned int num);
279+
280+int vringh_complete_iotlb(struct vringh *vrh, u16 head, u32 len);
281+
282+bool vringh_notify_enable_iotlb(struct vringh *vrh);
283+void vringh_notify_disable_iotlb(struct vringh *vrh);
284+
285+int vringh_need_notify_iotlb(struct vringh *vrh);
286+
251287 #endif /* _LINUX_VRINGH_H */