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