xref: /OK3568_Linux_fs/kernel/include/linux/vdpa.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _LINUX_VDPA_H
3*4882a593Smuzhiyun #define _LINUX_VDPA_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/kernel.h>
6*4882a593Smuzhiyun #include <linux/device.h>
7*4882a593Smuzhiyun #include <linux/interrupt.h>
8*4882a593Smuzhiyun #include <linux/vhost_iotlb.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun /**
11*4882a593Smuzhiyun  * vDPA callback definition.
12*4882a593Smuzhiyun  * @callback: interrupt callback function
13*4882a593Smuzhiyun  * @private: the data passed to the callback function
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun struct vdpa_callback {
16*4882a593Smuzhiyun 	irqreturn_t (*callback)(void *data);
17*4882a593Smuzhiyun 	void *private;
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /**
21*4882a593Smuzhiyun  * vDPA notification area
22*4882a593Smuzhiyun  * @addr: base address of the notification area
23*4882a593Smuzhiyun  * @size: size of the notification area
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun struct vdpa_notification_area {
26*4882a593Smuzhiyun 	resource_size_t addr;
27*4882a593Smuzhiyun 	resource_size_t size;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /**
31*4882a593Smuzhiyun  * vDPA vq_state definition
32*4882a593Smuzhiyun  * @avail_index: available index
33*4882a593Smuzhiyun  */
34*4882a593Smuzhiyun struct vdpa_vq_state {
35*4882a593Smuzhiyun 	u16	avail_index;
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /**
39*4882a593Smuzhiyun  * vDPA device - representation of a vDPA device
40*4882a593Smuzhiyun  * @dev: underlying device
41*4882a593Smuzhiyun  * @dma_dev: the actual device that is performing DMA
42*4882a593Smuzhiyun  * @config: the configuration ops for this device.
43*4882a593Smuzhiyun  * @index: device index
44*4882a593Smuzhiyun  * @features_valid: were features initialized? for legacy guests
45*4882a593Smuzhiyun  */
46*4882a593Smuzhiyun struct vdpa_device {
47*4882a593Smuzhiyun 	struct device dev;
48*4882a593Smuzhiyun 	struct device *dma_dev;
49*4882a593Smuzhiyun 	const struct vdpa_config_ops *config;
50*4882a593Smuzhiyun 	unsigned int index;
51*4882a593Smuzhiyun 	bool features_valid;
52*4882a593Smuzhiyun 	int nvqs;
53*4882a593Smuzhiyun };
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun /**
56*4882a593Smuzhiyun  * vDPA IOVA range - the IOVA range support by the device
57*4882a593Smuzhiyun  * @first: start of the IOVA range
58*4882a593Smuzhiyun  * @last: end of the IOVA range
59*4882a593Smuzhiyun  */
60*4882a593Smuzhiyun struct vdpa_iova_range {
61*4882a593Smuzhiyun 	u64 first;
62*4882a593Smuzhiyun 	u64 last;
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun  * vDPA_config_ops - operations for configuring a vDPA device.
67*4882a593Smuzhiyun  * Note: vDPA device drivers are required to implement all of the
68*4882a593Smuzhiyun  * operations unless it is mentioned to be optional in the following
69*4882a593Smuzhiyun  * list.
70*4882a593Smuzhiyun  *
71*4882a593Smuzhiyun  * @set_vq_address:		Set the address of virtqueue
72*4882a593Smuzhiyun  *				@vdev: vdpa device
73*4882a593Smuzhiyun  *				@idx: virtqueue index
74*4882a593Smuzhiyun  *				@desc_area: address of desc area
75*4882a593Smuzhiyun  *				@driver_area: address of driver area
76*4882a593Smuzhiyun  *				@device_area: address of device area
77*4882a593Smuzhiyun  *				Returns integer: success (0) or error (< 0)
78*4882a593Smuzhiyun  * @set_vq_num:			Set the size of virtqueue
79*4882a593Smuzhiyun  *				@vdev: vdpa device
80*4882a593Smuzhiyun  *				@idx: virtqueue index
81*4882a593Smuzhiyun  *				@num: the size of virtqueue
82*4882a593Smuzhiyun  * @kick_vq:			Kick the virtqueue
83*4882a593Smuzhiyun  *				@vdev: vdpa device
84*4882a593Smuzhiyun  *				@idx: virtqueue index
85*4882a593Smuzhiyun  * @set_vq_cb:			Set the interrupt callback function for
86*4882a593Smuzhiyun  *				a virtqueue
87*4882a593Smuzhiyun  *				@vdev: vdpa device
88*4882a593Smuzhiyun  *				@idx: virtqueue index
89*4882a593Smuzhiyun  *				@cb: virtio-vdev interrupt callback structure
90*4882a593Smuzhiyun  * @set_vq_ready:		Set ready status for a virtqueue
91*4882a593Smuzhiyun  *				@vdev: vdpa device
92*4882a593Smuzhiyun  *				@idx: virtqueue index
93*4882a593Smuzhiyun  *				@ready: ready (true) not ready(false)
94*4882a593Smuzhiyun  * @get_vq_ready:		Get ready status for a virtqueue
95*4882a593Smuzhiyun  *				@vdev: vdpa device
96*4882a593Smuzhiyun  *				@idx: virtqueue index
97*4882a593Smuzhiyun  *				Returns boolean: ready (true) or not (false)
98*4882a593Smuzhiyun  * @set_vq_state:		Set the state for a virtqueue
99*4882a593Smuzhiyun  *				@vdev: vdpa device
100*4882a593Smuzhiyun  *				@idx: virtqueue index
101*4882a593Smuzhiyun  *				@state: pointer to set virtqueue state (last_avail_idx)
102*4882a593Smuzhiyun  *				Returns integer: success (0) or error (< 0)
103*4882a593Smuzhiyun  * @get_vq_state:		Get the state for a virtqueue
104*4882a593Smuzhiyun  *				@vdev: vdpa device
105*4882a593Smuzhiyun  *				@idx: virtqueue index
106*4882a593Smuzhiyun  *				@state: pointer to returned state (last_avail_idx)
107*4882a593Smuzhiyun  * @get_vq_notification: 	Get the notification area for a virtqueue
108*4882a593Smuzhiyun  *				@vdev: vdpa device
109*4882a593Smuzhiyun  *				@idx: virtqueue index
110*4882a593Smuzhiyun  *				Returns the notifcation area
111*4882a593Smuzhiyun  * @get_vq_irq:			Get the irq number of a virtqueue (optional,
112*4882a593Smuzhiyun  *				but must implemented if require vq irq offloading)
113*4882a593Smuzhiyun  *				@vdev: vdpa device
114*4882a593Smuzhiyun  *				@idx: virtqueue index
115*4882a593Smuzhiyun  *				Returns int: irq number of a virtqueue,
116*4882a593Smuzhiyun  *				negative number if no irq assigned.
117*4882a593Smuzhiyun  * @get_vq_align:		Get the virtqueue align requirement
118*4882a593Smuzhiyun  *				for the device
119*4882a593Smuzhiyun  *				@vdev: vdpa device
120*4882a593Smuzhiyun  *				Returns virtqueue algin requirement
121*4882a593Smuzhiyun  * @get_features:		Get virtio features supported by the device
122*4882a593Smuzhiyun  *				@vdev: vdpa device
123*4882a593Smuzhiyun  *				Returns the virtio features support by the
124*4882a593Smuzhiyun  *				device
125*4882a593Smuzhiyun  * @set_features:		Set virtio features supported by the driver
126*4882a593Smuzhiyun  *				@vdev: vdpa device
127*4882a593Smuzhiyun  *				@features: feature support by the driver
128*4882a593Smuzhiyun  *				Returns integer: success (0) or error (< 0)
129*4882a593Smuzhiyun  * @set_config_cb:		Set the config interrupt callback
130*4882a593Smuzhiyun  *				@vdev: vdpa device
131*4882a593Smuzhiyun  *				@cb: virtio-vdev interrupt callback structure
132*4882a593Smuzhiyun  * @get_vq_num_max:		Get the max size of virtqueue
133*4882a593Smuzhiyun  *				@vdev: vdpa device
134*4882a593Smuzhiyun  *				Returns u16: max size of virtqueue
135*4882a593Smuzhiyun  * @get_device_id:		Get virtio device id
136*4882a593Smuzhiyun  *				@vdev: vdpa device
137*4882a593Smuzhiyun  *				Returns u32: virtio device id
138*4882a593Smuzhiyun  * @get_vendor_id:		Get id for the vendor that provides this device
139*4882a593Smuzhiyun  *				@vdev: vdpa device
140*4882a593Smuzhiyun  *				Returns u32: virtio vendor id
141*4882a593Smuzhiyun  * @get_status:			Get the device status
142*4882a593Smuzhiyun  *				@vdev: vdpa device
143*4882a593Smuzhiyun  *				Returns u8: virtio device status
144*4882a593Smuzhiyun  * @set_status:			Set the device status
145*4882a593Smuzhiyun  *				@vdev: vdpa device
146*4882a593Smuzhiyun  *				@status: virtio device status
147*4882a593Smuzhiyun  * @get_config:			Read from device specific configuration space
148*4882a593Smuzhiyun  *				@vdev: vdpa device
149*4882a593Smuzhiyun  *				@offset: offset from the beginning of
150*4882a593Smuzhiyun  *				configuration space
151*4882a593Smuzhiyun  *				@buf: buffer used to read to
152*4882a593Smuzhiyun  *				@len: the length to read from
153*4882a593Smuzhiyun  *				configuration space
154*4882a593Smuzhiyun  * @set_config:			Write to device specific configuration space
155*4882a593Smuzhiyun  *				@vdev: vdpa device
156*4882a593Smuzhiyun  *				@offset: offset from the beginning of
157*4882a593Smuzhiyun  *				configuration space
158*4882a593Smuzhiyun  *				@buf: buffer used to write from
159*4882a593Smuzhiyun  *				@len: the length to write to
160*4882a593Smuzhiyun  *				configuration space
161*4882a593Smuzhiyun  * @get_generation:		Get device config generation (optional)
162*4882a593Smuzhiyun  *				@vdev: vdpa device
163*4882a593Smuzhiyun  *				Returns u32: device generation
164*4882a593Smuzhiyun  * @get_iova_range:		Get supported iova range (optional)
165*4882a593Smuzhiyun  *				@vdev: vdpa device
166*4882a593Smuzhiyun  *				Returns the iova range supported by
167*4882a593Smuzhiyun  *				the device.
168*4882a593Smuzhiyun  * @set_map:			Set device memory mapping (optional)
169*4882a593Smuzhiyun  *				Needed for device that using device
170*4882a593Smuzhiyun  *				specific DMA translation (on-chip IOMMU)
171*4882a593Smuzhiyun  *				@vdev: vdpa device
172*4882a593Smuzhiyun  *				@iotlb: vhost memory mapping to be
173*4882a593Smuzhiyun  *				used by the vDPA
174*4882a593Smuzhiyun  *				Returns integer: success (0) or error (< 0)
175*4882a593Smuzhiyun  * @dma_map:			Map an area of PA to IOVA (optional)
176*4882a593Smuzhiyun  *				Needed for device that using device
177*4882a593Smuzhiyun  *				specific DMA translation (on-chip IOMMU)
178*4882a593Smuzhiyun  *				and preferring incremental map.
179*4882a593Smuzhiyun  *				@vdev: vdpa device
180*4882a593Smuzhiyun  *				@iova: iova to be mapped
181*4882a593Smuzhiyun  *				@size: size of the area
182*4882a593Smuzhiyun  *				@pa: physical address for the map
183*4882a593Smuzhiyun  *				@perm: device access permission (VHOST_MAP_XX)
184*4882a593Smuzhiyun  *				Returns integer: success (0) or error (< 0)
185*4882a593Smuzhiyun  * @dma_unmap:			Unmap an area of IOVA (optional but
186*4882a593Smuzhiyun  *				must be implemented with dma_map)
187*4882a593Smuzhiyun  *				Needed for device that using device
188*4882a593Smuzhiyun  *				specific DMA translation (on-chip IOMMU)
189*4882a593Smuzhiyun  *				and preferring incremental unmap.
190*4882a593Smuzhiyun  *				@vdev: vdpa device
191*4882a593Smuzhiyun  *				@iova: iova to be unmapped
192*4882a593Smuzhiyun  *				@size: size of the area
193*4882a593Smuzhiyun  *				Returns integer: success (0) or error (< 0)
194*4882a593Smuzhiyun  * @free:			Free resources that belongs to vDPA (optional)
195*4882a593Smuzhiyun  *				@vdev: vdpa device
196*4882a593Smuzhiyun  */
197*4882a593Smuzhiyun struct vdpa_config_ops {
198*4882a593Smuzhiyun 	/* Virtqueue ops */
199*4882a593Smuzhiyun 	int (*set_vq_address)(struct vdpa_device *vdev,
200*4882a593Smuzhiyun 			      u16 idx, u64 desc_area, u64 driver_area,
201*4882a593Smuzhiyun 			      u64 device_area);
202*4882a593Smuzhiyun 	void (*set_vq_num)(struct vdpa_device *vdev, u16 idx, u32 num);
203*4882a593Smuzhiyun 	void (*kick_vq)(struct vdpa_device *vdev, u16 idx);
204*4882a593Smuzhiyun 	void (*set_vq_cb)(struct vdpa_device *vdev, u16 idx,
205*4882a593Smuzhiyun 			  struct vdpa_callback *cb);
206*4882a593Smuzhiyun 	void (*set_vq_ready)(struct vdpa_device *vdev, u16 idx, bool ready);
207*4882a593Smuzhiyun 	bool (*get_vq_ready)(struct vdpa_device *vdev, u16 idx);
208*4882a593Smuzhiyun 	int (*set_vq_state)(struct vdpa_device *vdev, u16 idx,
209*4882a593Smuzhiyun 			    const struct vdpa_vq_state *state);
210*4882a593Smuzhiyun 	int (*get_vq_state)(struct vdpa_device *vdev, u16 idx,
211*4882a593Smuzhiyun 			    struct vdpa_vq_state *state);
212*4882a593Smuzhiyun 	struct vdpa_notification_area
213*4882a593Smuzhiyun 	(*get_vq_notification)(struct vdpa_device *vdev, u16 idx);
214*4882a593Smuzhiyun 	/* vq irq is not expected to be changed once DRIVER_OK is set */
215*4882a593Smuzhiyun 	int (*get_vq_irq)(struct vdpa_device *vdv, u16 idx);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	/* Device ops */
218*4882a593Smuzhiyun 	u32 (*get_vq_align)(struct vdpa_device *vdev);
219*4882a593Smuzhiyun 	u64 (*get_features)(struct vdpa_device *vdev);
220*4882a593Smuzhiyun 	int (*set_features)(struct vdpa_device *vdev, u64 features);
221*4882a593Smuzhiyun 	void (*set_config_cb)(struct vdpa_device *vdev,
222*4882a593Smuzhiyun 			      struct vdpa_callback *cb);
223*4882a593Smuzhiyun 	u16 (*get_vq_num_max)(struct vdpa_device *vdev);
224*4882a593Smuzhiyun 	u32 (*get_device_id)(struct vdpa_device *vdev);
225*4882a593Smuzhiyun 	u32 (*get_vendor_id)(struct vdpa_device *vdev);
226*4882a593Smuzhiyun 	u8 (*get_status)(struct vdpa_device *vdev);
227*4882a593Smuzhiyun 	void (*set_status)(struct vdpa_device *vdev, u8 status);
228*4882a593Smuzhiyun 	void (*get_config)(struct vdpa_device *vdev, unsigned int offset,
229*4882a593Smuzhiyun 			   void *buf, unsigned int len);
230*4882a593Smuzhiyun 	void (*set_config)(struct vdpa_device *vdev, unsigned int offset,
231*4882a593Smuzhiyun 			   const void *buf, unsigned int len);
232*4882a593Smuzhiyun 	u32 (*get_generation)(struct vdpa_device *vdev);
233*4882a593Smuzhiyun 	struct vdpa_iova_range (*get_iova_range)(struct vdpa_device *vdev);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	/* DMA ops */
236*4882a593Smuzhiyun 	int (*set_map)(struct vdpa_device *vdev, struct vhost_iotlb *iotlb);
237*4882a593Smuzhiyun 	int (*dma_map)(struct vdpa_device *vdev, u64 iova, u64 size,
238*4882a593Smuzhiyun 		       u64 pa, u32 perm);
239*4882a593Smuzhiyun 	int (*dma_unmap)(struct vdpa_device *vdev, u64 iova, u64 size);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	/* Free device resources */
242*4882a593Smuzhiyun 	void (*free)(struct vdpa_device *vdev);
243*4882a593Smuzhiyun };
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun struct vdpa_device *__vdpa_alloc_device(struct device *parent,
246*4882a593Smuzhiyun 					const struct vdpa_config_ops *config,
247*4882a593Smuzhiyun 					int nvqs,
248*4882a593Smuzhiyun 					size_t size);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun #define vdpa_alloc_device(dev_struct, member, parent, config, nvqs)   \
251*4882a593Smuzhiyun 			  container_of(__vdpa_alloc_device( \
252*4882a593Smuzhiyun 				       parent, config, nvqs, \
253*4882a593Smuzhiyun 				       sizeof(dev_struct) + \
254*4882a593Smuzhiyun 				       BUILD_BUG_ON_ZERO(offsetof( \
255*4882a593Smuzhiyun 				       dev_struct, member))), \
256*4882a593Smuzhiyun 				       dev_struct, member)
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun int vdpa_register_device(struct vdpa_device *vdev);
259*4882a593Smuzhiyun void vdpa_unregister_device(struct vdpa_device *vdev);
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun /**
262*4882a593Smuzhiyun  * vdpa_driver - operations for a vDPA driver
263*4882a593Smuzhiyun  * @driver: underlying device driver
264*4882a593Smuzhiyun  * @probe: the function to call when a device is found.  Returns 0 or -errno.
265*4882a593Smuzhiyun  * @remove: the function to call when a device is removed.
266*4882a593Smuzhiyun  */
267*4882a593Smuzhiyun struct vdpa_driver {
268*4882a593Smuzhiyun 	struct device_driver driver;
269*4882a593Smuzhiyun 	int (*probe)(struct vdpa_device *vdev);
270*4882a593Smuzhiyun 	void (*remove)(struct vdpa_device *vdev);
271*4882a593Smuzhiyun };
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun #define vdpa_register_driver(drv) \
274*4882a593Smuzhiyun 	__vdpa_register_driver(drv, THIS_MODULE)
275*4882a593Smuzhiyun int __vdpa_register_driver(struct vdpa_driver *drv, struct module *owner);
276*4882a593Smuzhiyun void vdpa_unregister_driver(struct vdpa_driver *drv);
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun #define module_vdpa_driver(__vdpa_driver) \
279*4882a593Smuzhiyun 	module_driver(__vdpa_driver, vdpa_register_driver,	\
280*4882a593Smuzhiyun 		      vdpa_unregister_driver)
281*4882a593Smuzhiyun 
drv_to_vdpa(struct device_driver * driver)282*4882a593Smuzhiyun static inline struct vdpa_driver *drv_to_vdpa(struct device_driver *driver)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	return container_of(driver, struct vdpa_driver, driver);
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun 
dev_to_vdpa(struct device * _dev)287*4882a593Smuzhiyun static inline struct vdpa_device *dev_to_vdpa(struct device *_dev)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun 	return container_of(_dev, struct vdpa_device, dev);
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun 
vdpa_get_drvdata(const struct vdpa_device * vdev)292*4882a593Smuzhiyun static inline void *vdpa_get_drvdata(const struct vdpa_device *vdev)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun 	return dev_get_drvdata(&vdev->dev);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun 
vdpa_set_drvdata(struct vdpa_device * vdev,void * data)297*4882a593Smuzhiyun static inline void vdpa_set_drvdata(struct vdpa_device *vdev, void *data)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun 	dev_set_drvdata(&vdev->dev, data);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun 
vdpa_get_dma_dev(struct vdpa_device * vdev)302*4882a593Smuzhiyun static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	return vdev->dma_dev;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun 
vdpa_reset(struct vdpa_device * vdev)307*4882a593Smuzhiyun static inline void vdpa_reset(struct vdpa_device *vdev)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun         const struct vdpa_config_ops *ops = vdev->config;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	vdev->features_valid = false;
312*4882a593Smuzhiyun         ops->set_status(vdev, 0);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
vdpa_set_features(struct vdpa_device * vdev,u64 features)315*4882a593Smuzhiyun static inline int vdpa_set_features(struct vdpa_device *vdev, u64 features)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun         const struct vdpa_config_ops *ops = vdev->config;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	vdev->features_valid = true;
320*4882a593Smuzhiyun         return ops->set_features(vdev, features);
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 
vdpa_get_config(struct vdpa_device * vdev,unsigned offset,void * buf,unsigned int len)324*4882a593Smuzhiyun static inline void vdpa_get_config(struct vdpa_device *vdev, unsigned offset,
325*4882a593Smuzhiyun 				   void *buf, unsigned int len)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun         const struct vdpa_config_ops *ops = vdev->config;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	/*
330*4882a593Smuzhiyun 	 * Config accesses aren't supposed to trigger before features are set.
331*4882a593Smuzhiyun 	 * If it does happen we assume a legacy guest.
332*4882a593Smuzhiyun 	 */
333*4882a593Smuzhiyun 	if (!vdev->features_valid)
334*4882a593Smuzhiyun 		vdpa_set_features(vdev, 0);
335*4882a593Smuzhiyun 	ops->get_config(vdev, offset, buf, len);
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun #endif /* _LINUX_VDPA_H */
339