0001
0002
0003
0004
0005
0006 #ifndef _VDPA_SIM_H
0007 #define _VDPA_SIM_H
0008
0009 #include <linux/iova.h>
0010 #include <linux/vringh.h>
0011 #include <linux/vdpa.h>
0012 #include <linux/virtio_byteorder.h>
0013 #include <linux/vhost_iotlb.h>
0014 #include <uapi/linux/virtio_config.h>
0015
0016 #define VDPASIM_FEATURES ((1ULL << VIRTIO_F_ANY_LAYOUT) | \
0017 (1ULL << VIRTIO_F_VERSION_1) | \
0018 (1ULL << VIRTIO_F_ACCESS_PLATFORM))
0019
0020 struct vdpasim;
0021
0022 struct vdpasim_virtqueue {
0023 struct vringh vring;
0024 struct vringh_kiov in_iov;
0025 struct vringh_kiov out_iov;
0026 unsigned short head;
0027 bool ready;
0028 u64 desc_addr;
0029 u64 device_addr;
0030 u64 driver_addr;
0031 u32 num;
0032 void *private;
0033 irqreturn_t (*cb)(void *data);
0034 };
0035
0036 struct vdpasim_dev_attr {
0037 struct vdpa_mgmt_dev *mgmt_dev;
0038 const char *name;
0039 u64 supported_features;
0040 size_t config_size;
0041 size_t buffer_size;
0042 int nvqs;
0043 u32 id;
0044 u32 ngroups;
0045 u32 nas;
0046
0047 work_func_t work_fn;
0048 void (*get_config)(struct vdpasim *vdpasim, void *config);
0049 void (*set_config)(struct vdpasim *vdpasim, const void *config);
0050 };
0051
0052
0053 struct vdpasim {
0054 struct vdpa_device vdpa;
0055 struct vdpasim_virtqueue *vqs;
0056 struct work_struct work;
0057 struct vdpasim_dev_attr dev_attr;
0058
0059 spinlock_t lock;
0060
0061 void *config;
0062 struct vhost_iotlb *iommu;
0063 struct iova_domain iova;
0064 void *buffer;
0065 u32 status;
0066 u32 generation;
0067 u64 features;
0068 u32 groups;
0069 bool running;
0070
0071 spinlock_t iommu_lock;
0072 };
0073
0074 struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *attr);
0075
0076
0077 static inline bool vdpasim_is_little_endian(struct vdpasim *vdpasim)
0078 {
0079 return virtio_legacy_is_little_endian() ||
0080 (vdpasim->features & (1ULL << VIRTIO_F_VERSION_1));
0081 }
0082
0083 static inline u16 vdpasim16_to_cpu(struct vdpasim *vdpasim, __virtio16 val)
0084 {
0085 return __virtio16_to_cpu(vdpasim_is_little_endian(vdpasim), val);
0086 }
0087
0088 static inline __virtio16 cpu_to_vdpasim16(struct vdpasim *vdpasim, u16 val)
0089 {
0090 return __cpu_to_virtio16(vdpasim_is_little_endian(vdpasim), val);
0091 }
0092
0093 static inline u32 vdpasim32_to_cpu(struct vdpasim *vdpasim, __virtio32 val)
0094 {
0095 return __virtio32_to_cpu(vdpasim_is_little_endian(vdpasim), val);
0096 }
0097
0098 static inline __virtio32 cpu_to_vdpasim32(struct vdpasim *vdpasim, u32 val)
0099 {
0100 return __cpu_to_virtio32(vdpasim_is_little_endian(vdpasim), val);
0101 }
0102
0103 static inline u64 vdpasim64_to_cpu(struct vdpasim *vdpasim, __virtio64 val)
0104 {
0105 return __virtio64_to_cpu(vdpasim_is_little_endian(vdpasim), val);
0106 }
0107
0108 static inline __virtio64 cpu_to_vdpasim64(struct vdpasim *vdpasim, u64 val)
0109 {
0110 return __cpu_to_virtio64(vdpasim_is_little_endian(vdpasim), val);
0111 }
0112
0113 #endif