192e87950SXie Yongji /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 292e87950SXie Yongji #ifndef _VDUSE_H_ 392e87950SXie Yongji #define _VDUSE_H_ 492e87950SXie Yongji 592e87950SXie Yongji #include <linux/types.h> 692e87950SXie Yongji 792e87950SXie Yongji #define VDUSE_BASE 0x81 892e87950SXie Yongji 992e87950SXie Yongji /* The ioctls for control device (/dev/vduse/control) */ 1092e87950SXie Yongji 1192e87950SXie Yongji #define VDUSE_API_VERSION 0 1292e87950SXie Yongji 1392e87950SXie Yongji /* 1492e87950SXie Yongji * Get the version of VDUSE API that kernel supported (VDUSE_API_VERSION). 1592e87950SXie Yongji * This is used for future extension. 1692e87950SXie Yongji */ 1792e87950SXie Yongji #define VDUSE_GET_API_VERSION _IOR(VDUSE_BASE, 0x00, __u64) 1892e87950SXie Yongji 1992e87950SXie Yongji /* Set the version of VDUSE API that userspace supported. */ 2092e87950SXie Yongji #define VDUSE_SET_API_VERSION _IOW(VDUSE_BASE, 0x01, __u64) 2192e87950SXie Yongji 2292e87950SXie Yongji /** 2392e87950SXie Yongji * struct vduse_dev_config - basic configuration of a VDUSE device 2492e87950SXie Yongji * @name: VDUSE device name, needs to be NUL terminated 2592e87950SXie Yongji * @vendor_id: virtio vendor id 2692e87950SXie Yongji * @device_id: virtio device id 2792e87950SXie Yongji * @features: virtio features 2892e87950SXie Yongji * @vq_num: the number of virtqueues 2992e87950SXie Yongji * @vq_align: the allocation alignment of virtqueue's metadata 3092e87950SXie Yongji * @reserved: for future use, needs to be initialized to zero 3192e87950SXie Yongji * @config_size: the size of the configuration space 3292e87950SXie Yongji * @config: the buffer of the configuration space 3392e87950SXie Yongji * 3492e87950SXie Yongji * Structure used by VDUSE_CREATE_DEV ioctl to create VDUSE device. 3592e87950SXie Yongji */ 3692e87950SXie Yongji struct vduse_dev_config { 3792e87950SXie Yongji #define VDUSE_NAME_MAX 256 3892e87950SXie Yongji char name[VDUSE_NAME_MAX]; 3992e87950SXie Yongji __u32 vendor_id; 4092e87950SXie Yongji __u32 device_id; 4192e87950SXie Yongji __u64 features; 4292e87950SXie Yongji __u32 vq_num; 4392e87950SXie Yongji __u32 vq_align; 4492e87950SXie Yongji __u32 reserved[13]; 4592e87950SXie Yongji __u32 config_size; 4692e87950SXie Yongji __u8 config[]; 4792e87950SXie Yongji }; 4892e87950SXie Yongji 4992e87950SXie Yongji /* Create a VDUSE device which is represented by a char device (/dev/vduse/$NAME) */ 5092e87950SXie Yongji #define VDUSE_CREATE_DEV _IOW(VDUSE_BASE, 0x02, struct vduse_dev_config) 5192e87950SXie Yongji 5292e87950SXie Yongji /* 5392e87950SXie Yongji * Destroy a VDUSE device. Make sure there are no more references 5492e87950SXie Yongji * to the char device (/dev/vduse/$NAME). 5592e87950SXie Yongji */ 5692e87950SXie Yongji #define VDUSE_DESTROY_DEV _IOW(VDUSE_BASE, 0x03, char[VDUSE_NAME_MAX]) 5792e87950SXie Yongji 5892e87950SXie Yongji /* The ioctls for VDUSE device (/dev/vduse/$NAME) */ 5992e87950SXie Yongji 6092e87950SXie Yongji /** 6192e87950SXie Yongji * struct vduse_iotlb_entry - entry of IOTLB to describe one IOVA region [start, last] 6292e87950SXie Yongji * @offset: the mmap offset on returned file descriptor 6392e87950SXie Yongji * @start: start of the IOVA region 6492e87950SXie Yongji * @last: last of the IOVA region 6592e87950SXie Yongji * @perm: access permission of the IOVA region 6692e87950SXie Yongji * 6792e87950SXie Yongji * Structure used by VDUSE_IOTLB_GET_FD ioctl to find an overlapped IOVA region. 6892e87950SXie Yongji */ 6992e87950SXie Yongji struct vduse_iotlb_entry { 7092e87950SXie Yongji __u64 offset; 7192e87950SXie Yongji __u64 start; 7292e87950SXie Yongji __u64 last; 7392e87950SXie Yongji #define VDUSE_ACCESS_RO 0x1 7492e87950SXie Yongji #define VDUSE_ACCESS_WO 0x2 7592e87950SXie Yongji #define VDUSE_ACCESS_RW 0x3 7692e87950SXie Yongji __u8 perm; 7792e87950SXie Yongji }; 7892e87950SXie Yongji 7992e87950SXie Yongji /* 8092e87950SXie Yongji * Find the first IOVA region that overlaps with the range [start, last] 8192e87950SXie Yongji * and return the corresponding file descriptor. Return -EINVAL means the 8292e87950SXie Yongji * IOVA region doesn't exist. Caller should set start and last fields. 8392e87950SXie Yongji */ 8492e87950SXie Yongji #define VDUSE_IOTLB_GET_FD _IOWR(VDUSE_BASE, 0x10, struct vduse_iotlb_entry) 8592e87950SXie Yongji 8692e87950SXie Yongji /* 8792e87950SXie Yongji * Get the negotiated virtio features. It's a subset of the features in 8892e87950SXie Yongji * struct vduse_dev_config which can be accepted by virtio driver. It's 8992e87950SXie Yongji * only valid after FEATURES_OK status bit is set. 9092e87950SXie Yongji */ 9192e87950SXie Yongji #define VDUSE_DEV_GET_FEATURES _IOR(VDUSE_BASE, 0x11, __u64) 9292e87950SXie Yongji 9392e87950SXie Yongji /** 9492e87950SXie Yongji * struct vduse_config_data - data used to update configuration space 9592e87950SXie Yongji * @offset: the offset from the beginning of configuration space 9692e87950SXie Yongji * @length: the length to write to configuration space 9792e87950SXie Yongji * @buffer: the buffer used to write from 9892e87950SXie Yongji * 9992e87950SXie Yongji * Structure used by VDUSE_DEV_SET_CONFIG ioctl to update device 10092e87950SXie Yongji * configuration space. 10192e87950SXie Yongji */ 10292e87950SXie Yongji struct vduse_config_data { 10392e87950SXie Yongji __u32 offset; 10492e87950SXie Yongji __u32 length; 10592e87950SXie Yongji __u8 buffer[]; 10692e87950SXie Yongji }; 10792e87950SXie Yongji 10892e87950SXie Yongji /* Set device configuration space */ 10992e87950SXie Yongji #define VDUSE_DEV_SET_CONFIG _IOW(VDUSE_BASE, 0x12, struct vduse_config_data) 11092e87950SXie Yongji 11192e87950SXie Yongji /* 11292e87950SXie Yongji * Inject a config interrupt. It's usually used to notify virtio driver 11392e87950SXie Yongji * that device configuration space has changed. 11492e87950SXie Yongji */ 11592e87950SXie Yongji #define VDUSE_DEV_INJECT_CONFIG_IRQ _IO(VDUSE_BASE, 0x13) 11692e87950SXie Yongji 11792e87950SXie Yongji /** 11892e87950SXie Yongji * struct vduse_vq_config - basic configuration of a virtqueue 11992e87950SXie Yongji * @index: virtqueue index 12092e87950SXie Yongji * @max_size: the max size of virtqueue 12192e87950SXie Yongji * @reserved: for future use, needs to be initialized to zero 12292e87950SXie Yongji * 12392e87950SXie Yongji * Structure used by VDUSE_VQ_SETUP ioctl to setup a virtqueue. 12492e87950SXie Yongji */ 12592e87950SXie Yongji struct vduse_vq_config { 12692e87950SXie Yongji __u32 index; 12792e87950SXie Yongji __u16 max_size; 12892e87950SXie Yongji __u16 reserved[13]; 12992e87950SXie Yongji }; 13092e87950SXie Yongji 13192e87950SXie Yongji /* 13292e87950SXie Yongji * Setup the specified virtqueue. Make sure all virtqueues have been 13392e87950SXie Yongji * configured before the device is attached to vDPA bus. 13492e87950SXie Yongji */ 13592e87950SXie Yongji #define VDUSE_VQ_SETUP _IOW(VDUSE_BASE, 0x14, struct vduse_vq_config) 13692e87950SXie Yongji 13792e87950SXie Yongji /** 13892e87950SXie Yongji * struct vduse_vq_state_split - split virtqueue state 13992e87950SXie Yongji * @avail_index: available index 14092e87950SXie Yongji */ 14192e87950SXie Yongji struct vduse_vq_state_split { 14292e87950SXie Yongji __u16 avail_index; 14392e87950SXie Yongji }; 14492e87950SXie Yongji 14592e87950SXie Yongji /** 14692e87950SXie Yongji * struct vduse_vq_state_packed - packed virtqueue state 14792e87950SXie Yongji * @last_avail_counter: last driver ring wrap counter observed by device 14892e87950SXie Yongji * @last_avail_idx: device available index 14992e87950SXie Yongji * @last_used_counter: device ring wrap counter 15092e87950SXie Yongji * @last_used_idx: used index 15192e87950SXie Yongji */ 15292e87950SXie Yongji struct vduse_vq_state_packed { 15392e87950SXie Yongji __u16 last_avail_counter; 15492e87950SXie Yongji __u16 last_avail_idx; 15592e87950SXie Yongji __u16 last_used_counter; 15692e87950SXie Yongji __u16 last_used_idx; 15792e87950SXie Yongji }; 15892e87950SXie Yongji 15992e87950SXie Yongji /** 16092e87950SXie Yongji * struct vduse_vq_info - information of a virtqueue 16192e87950SXie Yongji * @index: virtqueue index 16292e87950SXie Yongji * @num: the size of virtqueue 16392e87950SXie Yongji * @desc_addr: address of desc area 16492e87950SXie Yongji * @driver_addr: address of driver area 16592e87950SXie Yongji * @device_addr: address of device area 16692e87950SXie Yongji * @split: split virtqueue state 16792e87950SXie Yongji * @packed: packed virtqueue state 16892e87950SXie Yongji * @ready: ready status of virtqueue 16992e87950SXie Yongji * 17092e87950SXie Yongji * Structure used by VDUSE_VQ_GET_INFO ioctl to get virtqueue's information. 17192e87950SXie Yongji */ 17292e87950SXie Yongji struct vduse_vq_info { 17392e87950SXie Yongji __u32 index; 17492e87950SXie Yongji __u32 num; 17592e87950SXie Yongji __u64 desc_addr; 17692e87950SXie Yongji __u64 driver_addr; 17792e87950SXie Yongji __u64 device_addr; 17892e87950SXie Yongji union { 17992e87950SXie Yongji struct vduse_vq_state_split split; 18092e87950SXie Yongji struct vduse_vq_state_packed packed; 18192e87950SXie Yongji }; 18292e87950SXie Yongji __u8 ready; 18392e87950SXie Yongji }; 18492e87950SXie Yongji 18592e87950SXie Yongji /* Get the specified virtqueue's information. Caller should set index field. */ 18692e87950SXie Yongji #define VDUSE_VQ_GET_INFO _IOWR(VDUSE_BASE, 0x15, struct vduse_vq_info) 18792e87950SXie Yongji 18892e87950SXie Yongji /** 18992e87950SXie Yongji * struct vduse_vq_eventfd - eventfd configuration for a virtqueue 19092e87950SXie Yongji * @index: virtqueue index 19192e87950SXie Yongji * @fd: eventfd, -1 means de-assigning the eventfd 19292e87950SXie Yongji * 19392e87950SXie Yongji * Structure used by VDUSE_VQ_SETUP_KICKFD ioctl to setup kick eventfd. 19492e87950SXie Yongji */ 19592e87950SXie Yongji struct vduse_vq_eventfd { 19692e87950SXie Yongji __u32 index; 19792e87950SXie Yongji #define VDUSE_EVENTFD_DEASSIGN -1 19892e87950SXie Yongji int fd; 19992e87950SXie Yongji }; 20092e87950SXie Yongji 20192e87950SXie Yongji /* 20292e87950SXie Yongji * Setup kick eventfd for specified virtqueue. The kick eventfd is used 20392e87950SXie Yongji * by VDUSE kernel module to notify userspace to consume the avail vring. 20492e87950SXie Yongji */ 20592e87950SXie Yongji #define VDUSE_VQ_SETUP_KICKFD _IOW(VDUSE_BASE, 0x16, struct vduse_vq_eventfd) 20692e87950SXie Yongji 20792e87950SXie Yongji /* 20892e87950SXie Yongji * Inject an interrupt for specific virtqueue. It's used to notify virtio driver 20992e87950SXie Yongji * to consume the used vring. 21092e87950SXie Yongji */ 21192e87950SXie Yongji #define VDUSE_VQ_INJECT_IRQ _IOW(VDUSE_BASE, 0x17, __u32) 21292e87950SXie Yongji 213*d525f73fSChenyi Qiang /** 214*d525f73fSChenyi Qiang * struct vduse_iova_umem - userspace memory configuration for one IOVA region 215*d525f73fSChenyi Qiang * @uaddr: start address of userspace memory, it must be aligned to page size 216*d525f73fSChenyi Qiang * @iova: start of the IOVA region 217*d525f73fSChenyi Qiang * @size: size of the IOVA region 218*d525f73fSChenyi Qiang * @reserved: for future use, needs to be initialized to zero 219*d525f73fSChenyi Qiang * 220*d525f73fSChenyi Qiang * Structure used by VDUSE_IOTLB_REG_UMEM and VDUSE_IOTLB_DEREG_UMEM 221*d525f73fSChenyi Qiang * ioctls to register/de-register userspace memory for IOVA regions 222*d525f73fSChenyi Qiang */ 223*d525f73fSChenyi Qiang struct vduse_iova_umem { 224*d525f73fSChenyi Qiang __u64 uaddr; 225*d525f73fSChenyi Qiang __u64 iova; 226*d525f73fSChenyi Qiang __u64 size; 227*d525f73fSChenyi Qiang __u64 reserved[3]; 228*d525f73fSChenyi Qiang }; 229*d525f73fSChenyi Qiang 230*d525f73fSChenyi Qiang /* Register userspace memory for IOVA regions */ 231*d525f73fSChenyi Qiang #define VDUSE_IOTLB_REG_UMEM _IOW(VDUSE_BASE, 0x18, struct vduse_iova_umem) 232*d525f73fSChenyi Qiang 233*d525f73fSChenyi Qiang /* De-register the userspace memory. Caller should set iova and size field. */ 234*d525f73fSChenyi Qiang #define VDUSE_IOTLB_DEREG_UMEM _IOW(VDUSE_BASE, 0x19, struct vduse_iova_umem) 235*d525f73fSChenyi Qiang 236*d525f73fSChenyi Qiang /** 237*d525f73fSChenyi Qiang * struct vduse_iova_info - information of one IOVA region 238*d525f73fSChenyi Qiang * @start: start of the IOVA region 239*d525f73fSChenyi Qiang * @last: last of the IOVA region 240*d525f73fSChenyi Qiang * @capability: capability of the IOVA regsion 241*d525f73fSChenyi Qiang * @reserved: for future use, needs to be initialized to zero 242*d525f73fSChenyi Qiang * 243*d525f73fSChenyi Qiang * Structure used by VDUSE_IOTLB_GET_INFO ioctl to get information of 244*d525f73fSChenyi Qiang * one IOVA region. 245*d525f73fSChenyi Qiang */ 246*d525f73fSChenyi Qiang struct vduse_iova_info { 247*d525f73fSChenyi Qiang __u64 start; 248*d525f73fSChenyi Qiang __u64 last; 249*d525f73fSChenyi Qiang #define VDUSE_IOVA_CAP_UMEM (1 << 0) 250*d525f73fSChenyi Qiang __u64 capability; 251*d525f73fSChenyi Qiang __u64 reserved[3]; 252*d525f73fSChenyi Qiang }; 253*d525f73fSChenyi Qiang 254*d525f73fSChenyi Qiang /* 255*d525f73fSChenyi Qiang * Find the first IOVA region that overlaps with the range [start, last] 256*d525f73fSChenyi Qiang * and return some information on it. Caller should set start and last fields. 257*d525f73fSChenyi Qiang */ 258*d525f73fSChenyi Qiang #define VDUSE_IOTLB_GET_INFO _IOWR(VDUSE_BASE, 0x1a, struct vduse_iova_info) 259*d525f73fSChenyi Qiang 26092e87950SXie Yongji /* The control messages definition for read(2)/write(2) on /dev/vduse/$NAME */ 26192e87950SXie Yongji 26292e87950SXie Yongji /** 26392e87950SXie Yongji * enum vduse_req_type - request type 26492e87950SXie Yongji * @VDUSE_GET_VQ_STATE: get the state for specified virtqueue from userspace 26592e87950SXie Yongji * @VDUSE_SET_STATUS: set the device status 26692e87950SXie Yongji * @VDUSE_UPDATE_IOTLB: Notify userspace to update the memory mapping for 26792e87950SXie Yongji * specified IOVA range via VDUSE_IOTLB_GET_FD ioctl 26892e87950SXie Yongji */ 26992e87950SXie Yongji enum vduse_req_type { 27092e87950SXie Yongji VDUSE_GET_VQ_STATE, 27192e87950SXie Yongji VDUSE_SET_STATUS, 27292e87950SXie Yongji VDUSE_UPDATE_IOTLB, 27392e87950SXie Yongji }; 27492e87950SXie Yongji 27592e87950SXie Yongji /** 27692e87950SXie Yongji * struct vduse_vq_state - virtqueue state 27792e87950SXie Yongji * @index: virtqueue index 27892e87950SXie Yongji * @split: split virtqueue state 27992e87950SXie Yongji * @packed: packed virtqueue state 28092e87950SXie Yongji */ 28192e87950SXie Yongji struct vduse_vq_state { 28292e87950SXie Yongji __u32 index; 28392e87950SXie Yongji union { 28492e87950SXie Yongji struct vduse_vq_state_split split; 28592e87950SXie Yongji struct vduse_vq_state_packed packed; 28692e87950SXie Yongji }; 28792e87950SXie Yongji }; 28892e87950SXie Yongji 28992e87950SXie Yongji /** 29092e87950SXie Yongji * struct vduse_dev_status - device status 29192e87950SXie Yongji * @status: device status 29292e87950SXie Yongji */ 29392e87950SXie Yongji struct vduse_dev_status { 29492e87950SXie Yongji __u8 status; 29592e87950SXie Yongji }; 29692e87950SXie Yongji 29792e87950SXie Yongji /** 29892e87950SXie Yongji * struct vduse_iova_range - IOVA range [start, last] 29992e87950SXie Yongji * @start: start of the IOVA range 30092e87950SXie Yongji * @last: last of the IOVA range 30192e87950SXie Yongji */ 30292e87950SXie Yongji struct vduse_iova_range { 30392e87950SXie Yongji __u64 start; 30492e87950SXie Yongji __u64 last; 30592e87950SXie Yongji }; 30692e87950SXie Yongji 30792e87950SXie Yongji /** 30892e87950SXie Yongji * struct vduse_dev_request - control request 30992e87950SXie Yongji * @type: request type 31092e87950SXie Yongji * @request_id: request id 31192e87950SXie Yongji * @reserved: for future use 31292e87950SXie Yongji * @vq_state: virtqueue state, only index field is available 31392e87950SXie Yongji * @s: device status 31492e87950SXie Yongji * @iova: IOVA range for updating 31592e87950SXie Yongji * @padding: padding 31692e87950SXie Yongji * 31792e87950SXie Yongji * Structure used by read(2) on /dev/vduse/$NAME. 31892e87950SXie Yongji */ 31992e87950SXie Yongji struct vduse_dev_request { 32092e87950SXie Yongji __u32 type; 32192e87950SXie Yongji __u32 request_id; 32292e87950SXie Yongji __u32 reserved[4]; 32392e87950SXie Yongji union { 32492e87950SXie Yongji struct vduse_vq_state vq_state; 32592e87950SXie Yongji struct vduse_dev_status s; 32692e87950SXie Yongji struct vduse_iova_range iova; 32792e87950SXie Yongji __u32 padding[32]; 32892e87950SXie Yongji }; 32992e87950SXie Yongji }; 33092e87950SXie Yongji 33192e87950SXie Yongji /** 33292e87950SXie Yongji * struct vduse_dev_response - response to control request 33392e87950SXie Yongji * @request_id: corresponding request id 33492e87950SXie Yongji * @result: the result of request 33592e87950SXie Yongji * @reserved: for future use, needs to be initialized to zero 33692e87950SXie Yongji * @vq_state: virtqueue state 33792e87950SXie Yongji * @padding: padding 33892e87950SXie Yongji * 33992e87950SXie Yongji * Structure used by write(2) on /dev/vduse/$NAME. 34092e87950SXie Yongji */ 34192e87950SXie Yongji struct vduse_dev_response { 34292e87950SXie Yongji __u32 request_id; 34392e87950SXie Yongji #define VDUSE_REQ_RESULT_OK 0x00 34492e87950SXie Yongji #define VDUSE_REQ_RESULT_FAILED 0x01 34592e87950SXie Yongji __u32 result; 34692e87950SXie Yongji __u32 reserved[4]; 34792e87950SXie Yongji union { 34892e87950SXie Yongji struct vduse_vq_state vq_state; 34992e87950SXie Yongji __u32 padding[32]; 35092e87950SXie Yongji }; 35192e87950SXie Yongji }; 35292e87950SXie Yongji 35392e87950SXie Yongji #endif /* _VDUSE_H_ */ 354