xref: /openbmc/linux/drivers/vdpa/vdpa_sim/vdpa_sim.h (revision 112f23cd)
1db1e8bb6SMax Gurtovoy /* SPDX-License-Identifier: GPL-2.0 */
2db1e8bb6SMax Gurtovoy /*
3db1e8bb6SMax Gurtovoy  * Copyright (c) 2020, Red Hat Inc. All rights reserved.
4db1e8bb6SMax Gurtovoy  */
5db1e8bb6SMax Gurtovoy 
6db1e8bb6SMax Gurtovoy #ifndef _VDPA_SIM_H
7db1e8bb6SMax Gurtovoy #define _VDPA_SIM_H
8db1e8bb6SMax Gurtovoy 
94080fc10SStefano Garzarella #include <linux/iova.h>
10db1e8bb6SMax Gurtovoy #include <linux/vringh.h>
11db1e8bb6SMax Gurtovoy #include <linux/vdpa.h>
12db1e8bb6SMax Gurtovoy #include <linux/virtio_byteorder.h>
13db1e8bb6SMax Gurtovoy #include <linux/vhost_iotlb.h>
14db1e8bb6SMax Gurtovoy #include <uapi/linux/virtio_config.h>
15db1e8bb6SMax Gurtovoy 
16db1e8bb6SMax Gurtovoy #define VDPASIM_FEATURES	((1ULL << VIRTIO_F_ANY_LAYOUT) | \
17db1e8bb6SMax Gurtovoy 				 (1ULL << VIRTIO_F_VERSION_1)  | \
18db1e8bb6SMax Gurtovoy 				 (1ULL << VIRTIO_F_ACCESS_PLATFORM))
19db1e8bb6SMax Gurtovoy 
20db1e8bb6SMax Gurtovoy struct vdpasim;
21db1e8bb6SMax Gurtovoy 
22db1e8bb6SMax Gurtovoy struct vdpasim_virtqueue {
23db1e8bb6SMax Gurtovoy 	struct vringh vring;
24db1e8bb6SMax Gurtovoy 	struct vringh_kiov in_iov;
25db1e8bb6SMax Gurtovoy 	struct vringh_kiov out_iov;
26db1e8bb6SMax Gurtovoy 	unsigned short head;
27db1e8bb6SMax Gurtovoy 	bool ready;
28db1e8bb6SMax Gurtovoy 	u64 desc_addr;
29db1e8bb6SMax Gurtovoy 	u64 device_addr;
30db1e8bb6SMax Gurtovoy 	u64 driver_addr;
31db1e8bb6SMax Gurtovoy 	u32 num;
32db1e8bb6SMax Gurtovoy 	void *private;
33db1e8bb6SMax Gurtovoy 	irqreturn_t (*cb)(void *data);
34db1e8bb6SMax Gurtovoy };
35db1e8bb6SMax Gurtovoy 
36db1e8bb6SMax Gurtovoy struct vdpasim_dev_attr {
37a3c06ae1SParav Pandit 	struct vdpa_mgmt_dev *mgmt_dev;
38a3c06ae1SParav Pandit 	const char *name;
39db1e8bb6SMax Gurtovoy 	u64 supported_features;
40bb105d51SJason Wang 	size_t alloc_size;
41db1e8bb6SMax Gurtovoy 	size_t config_size;
42db1e8bb6SMax Gurtovoy 	int nvqs;
43db1e8bb6SMax Gurtovoy 	u32 id;
44bda324fdSGautam Dawar 	u32 ngroups;
45bda324fdSGautam Dawar 	u32 nas;
46db1e8bb6SMax Gurtovoy 
47e2a4f808SStefano Garzarella 	void (*work_fn)(struct vdpasim *vdpasim);
48db1e8bb6SMax Gurtovoy 	void (*get_config)(struct vdpasim *vdpasim, void *config);
49db1e8bb6SMax Gurtovoy 	void (*set_config)(struct vdpasim *vdpasim, const void *config);
505dbb063aSJason Wang 	int (*get_stats)(struct vdpasim *vdpasim, u16 idx,
515dbb063aSJason Wang 			 struct sk_buff *msg,
525dbb063aSJason Wang 			 struct netlink_ext_ack *extack);
53*112f23cdSStefano Garzarella 	void (*free)(struct vdpasim *vdpasim);
54db1e8bb6SMax Gurtovoy };
55db1e8bb6SMax Gurtovoy 
56db1e8bb6SMax Gurtovoy /* State of each vdpasim device */
57db1e8bb6SMax Gurtovoy struct vdpasim {
58db1e8bb6SMax Gurtovoy 	struct vdpa_device vdpa;
59db1e8bb6SMax Gurtovoy 	struct vdpasim_virtqueue *vqs;
6076acfa7bSStefano Garzarella 	struct kthread_worker *worker;
6176acfa7bSStefano Garzarella 	struct kthread_work work;
624bb94d2dSStefano Garzarella 	struct mm_struct *mm_bound;
63db1e8bb6SMax Gurtovoy 	struct vdpasim_dev_attr dev_attr;
64d7621c28SStefano Garzarella 	/* mutex to synchronize virtqueue state */
65d7621c28SStefano Garzarella 	struct mutex mutex;
66db1e8bb6SMax Gurtovoy 	/* virtio config according to device type */
67db1e8bb6SMax Gurtovoy 	void *config;
68db1e8bb6SMax Gurtovoy 	struct vhost_iotlb *iommu;
696c3d329eSJason Wang 	bool *iommu_pt;
70db1e8bb6SMax Gurtovoy 	u32 status;
71db1e8bb6SMax Gurtovoy 	u32 generation;
72db1e8bb6SMax Gurtovoy 	u64 features;
73d4821902SGautam Dawar 	u32 groups;
740c89e2a3SEugenio Pérez 	bool running;
75f9d9f57eSSebastien Boeuf 	bool pending_kick;
76db1e8bb6SMax Gurtovoy 	/* spinlock to synchronize iommu table */
77db1e8bb6SMax Gurtovoy 	spinlock_t iommu_lock;
78db1e8bb6SMax Gurtovoy };
79db1e8bb6SMax Gurtovoy 
80477f7197SJason Wang struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *attr,
81477f7197SJason Wang 			       const struct vdpa_dev_set_config *config);
82e2a4f808SStefano Garzarella void vdpasim_schedule_work(struct vdpasim *vdpasim);
83db1e8bb6SMax Gurtovoy 
84db1e8bb6SMax Gurtovoy /* TODO: cross-endian support */
vdpasim_is_little_endian(struct vdpasim * vdpasim)85db1e8bb6SMax Gurtovoy static inline bool vdpasim_is_little_endian(struct vdpasim *vdpasim)
86db1e8bb6SMax Gurtovoy {
87db1e8bb6SMax Gurtovoy 	return virtio_legacy_is_little_endian() ||
88db1e8bb6SMax Gurtovoy 		(vdpasim->features & (1ULL << VIRTIO_F_VERSION_1));
89db1e8bb6SMax Gurtovoy }
90db1e8bb6SMax Gurtovoy 
vdpasim16_to_cpu(struct vdpasim * vdpasim,__virtio16 val)91db1e8bb6SMax Gurtovoy static inline u16 vdpasim16_to_cpu(struct vdpasim *vdpasim, __virtio16 val)
92db1e8bb6SMax Gurtovoy {
93db1e8bb6SMax Gurtovoy 	return __virtio16_to_cpu(vdpasim_is_little_endian(vdpasim), val);
94db1e8bb6SMax Gurtovoy }
95db1e8bb6SMax Gurtovoy 
cpu_to_vdpasim16(struct vdpasim * vdpasim,u16 val)96db1e8bb6SMax Gurtovoy static inline __virtio16 cpu_to_vdpasim16(struct vdpasim *vdpasim, u16 val)
97db1e8bb6SMax Gurtovoy {
98db1e8bb6SMax Gurtovoy 	return __cpu_to_virtio16(vdpasim_is_little_endian(vdpasim), val);
99db1e8bb6SMax Gurtovoy }
100db1e8bb6SMax Gurtovoy 
vdpasim32_to_cpu(struct vdpasim * vdpasim,__virtio32 val)101db1e8bb6SMax Gurtovoy static inline u32 vdpasim32_to_cpu(struct vdpasim *vdpasim, __virtio32 val)
102db1e8bb6SMax Gurtovoy {
103db1e8bb6SMax Gurtovoy 	return __virtio32_to_cpu(vdpasim_is_little_endian(vdpasim), val);
104db1e8bb6SMax Gurtovoy }
105db1e8bb6SMax Gurtovoy 
cpu_to_vdpasim32(struct vdpasim * vdpasim,u32 val)106db1e8bb6SMax Gurtovoy static inline __virtio32 cpu_to_vdpasim32(struct vdpasim *vdpasim, u32 val)
107db1e8bb6SMax Gurtovoy {
108db1e8bb6SMax Gurtovoy 	return __cpu_to_virtio32(vdpasim_is_little_endian(vdpasim), val);
109db1e8bb6SMax Gurtovoy }
110db1e8bb6SMax Gurtovoy 
vdpasim64_to_cpu(struct vdpasim * vdpasim,__virtio64 val)111db1e8bb6SMax Gurtovoy static inline u64 vdpasim64_to_cpu(struct vdpasim *vdpasim, __virtio64 val)
112db1e8bb6SMax Gurtovoy {
113db1e8bb6SMax Gurtovoy 	return __virtio64_to_cpu(vdpasim_is_little_endian(vdpasim), val);
114db1e8bb6SMax Gurtovoy }
115db1e8bb6SMax Gurtovoy 
cpu_to_vdpasim64(struct vdpasim * vdpasim,u64 val)116db1e8bb6SMax Gurtovoy static inline __virtio64 cpu_to_vdpasim64(struct vdpasim *vdpasim, u64 val)
117db1e8bb6SMax Gurtovoy {
118db1e8bb6SMax Gurtovoy 	return __cpu_to_virtio64(vdpasim_is_little_endian(vdpasim), val);
119db1e8bb6SMax Gurtovoy }
120db1e8bb6SMax Gurtovoy 
121db1e8bb6SMax Gurtovoy #endif
122