Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (c) 2020, Red Hat Inc. All rights reserved.
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 /* State of each vdpasim device */
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     /* spinlock to synchronize virtqueue state */
0059     spinlock_t lock;
0060     /* virtio config according to device type */
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     /* spinlock to synchronize iommu table */
0071     spinlock_t iommu_lock;
0072 };
0073 
0074 struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *attr);
0075 
0076 /* TODO: cross-endian support */
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