linux/include/linux/virtio_config.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _LINUX_VIRTIO_CONFIG_H
   3#define _LINUX_VIRTIO_CONFIG_H
   4
   5#include <linux/err.h>
   6#include <linux/bug.h>
   7#include <linux/virtio.h>
   8#include <linux/virtio_byteorder.h>
   9#include <linux/compiler_types.h>
  10#include <uapi/linux/virtio_config.h>
  11
  12struct irq_affinity;
  13
  14struct virtio_shm_region {
  15        u64 addr;
  16        u64 len;
  17};
  18
  19/**
  20 * virtio_config_ops - operations for configuring a virtio device
  21 * Note: Do not assume that a transport implements all of the operations
  22 *       getting/setting a value as a simple read/write! Generally speaking,
  23 *       any of @get/@set, @get_status/@set_status, or @get_features/
  24 *       @finalize_features are NOT safe to be called from an atomic
  25 *       context.
  26 * @get: read the value of a configuration field
  27 *      vdev: the virtio_device
  28 *      offset: the offset of the configuration field
  29 *      buf: the buffer to write the field value into.
  30 *      len: the length of the buffer
  31 * @set: write the value of a configuration field
  32 *      vdev: the virtio_device
  33 *      offset: the offset of the configuration field
  34 *      buf: the buffer to read the field value from.
  35 *      len: the length of the buffer
  36 * @generation: config generation counter (optional)
  37 *      vdev: the virtio_device
  38 *      Returns the config generation counter
  39 * @get_status: read the status byte
  40 *      vdev: the virtio_device
  41 *      Returns the status byte
  42 * @set_status: write the status byte
  43 *      vdev: the virtio_device
  44 *      status: the new status byte
  45 * @reset: reset the device
  46 *      vdev: the virtio device
  47 *      After this, status and feature negotiation must be done again
  48 *      Device must not be reset from its vq/config callbacks, or in
  49 *      parallel with being added/removed.
  50 * @find_vqs: find virtqueues and instantiate them.
  51 *      vdev: the virtio_device
  52 *      nvqs: the number of virtqueues to find
  53 *      vqs: on success, includes new virtqueues
  54 *      callbacks: array of callbacks, for each virtqueue
  55 *              include a NULL entry for vqs that do not need a callback
  56 *      names: array of virtqueue names (mainly for debugging)
  57 *              include a NULL entry for vqs unused by driver
  58 *      Returns 0 on success or error status
  59 * @del_vqs: free virtqueues found by find_vqs().
  60 * @get_features: get the array of feature bits for this device.
  61 *      vdev: the virtio_device
  62 *      Returns the first 64 feature bits (all we currently need).
  63 * @finalize_features: confirm what device features we'll be using.
  64 *      vdev: the virtio_device
  65 *      This gives the final feature bits for the device: it can change
  66 *      the dev->feature bits if it wants.
  67 *      Returns 0 on success or error status
  68 * @bus_name: return the bus name associated with the device (optional)
  69 *      vdev: the virtio_device
  70 *      This returns a pointer to the bus name a la pci_name from which
  71 *      the caller can then copy.
  72 * @set_vq_affinity: set the affinity for a virtqueue (optional).
  73 * @get_vq_affinity: get the affinity for a virtqueue (optional).
  74 * @get_shm_region: get a shared memory region based on the index.
  75 */
  76typedef void vq_callback_t(struct virtqueue *);
  77struct virtio_config_ops {
  78        void (*get)(struct virtio_device *vdev, unsigned offset,
  79                    void *buf, unsigned len);
  80        void (*set)(struct virtio_device *vdev, unsigned offset,
  81                    const void *buf, unsigned len);
  82        u32 (*generation)(struct virtio_device *vdev);
  83        u8 (*get_status)(struct virtio_device *vdev);
  84        void (*set_status)(struct virtio_device *vdev, u8 status);
  85        void (*reset)(struct virtio_device *vdev);
  86        int (*find_vqs)(struct virtio_device *, unsigned nvqs,
  87                        struct virtqueue *vqs[], vq_callback_t *callbacks[],
  88                        const char * const names[], const bool *ctx,
  89                        struct irq_affinity *desc);
  90        void (*del_vqs)(struct virtio_device *);
  91        u64 (*get_features)(struct virtio_device *vdev);
  92        int (*finalize_features)(struct virtio_device *vdev);
  93        const char *(*bus_name)(struct virtio_device *vdev);
  94        int (*set_vq_affinity)(struct virtqueue *vq,
  95                               const struct cpumask *cpu_mask);
  96        const struct cpumask *(*get_vq_affinity)(struct virtio_device *vdev,
  97                        int index);
  98        bool (*get_shm_region)(struct virtio_device *vdev,
  99                               struct virtio_shm_region *region, u8 id);
 100};
 101
 102/* If driver didn't advertise the feature, it will never appear. */
 103void virtio_check_driver_offered_feature(const struct virtio_device *vdev,
 104                                         unsigned int fbit);
 105
 106/**
 107 * __virtio_test_bit - helper to test feature bits. For use by transports.
 108 *                     Devices should normally use virtio_has_feature,
 109 *                     which includes more checks.
 110 * @vdev: the device
 111 * @fbit: the feature bit
 112 */
 113static inline bool __virtio_test_bit(const struct virtio_device *vdev,
 114                                     unsigned int fbit)
 115{
 116        /* Did you forget to fix assumptions on max features? */
 117        if (__builtin_constant_p(fbit))
 118                BUILD_BUG_ON(fbit >= 64);
 119        else
 120                BUG_ON(fbit >= 64);
 121
 122        return vdev->features & BIT_ULL(fbit);
 123}
 124
 125/**
 126 * __virtio_set_bit - helper to set feature bits. For use by transports.
 127 * @vdev: the device
 128 * @fbit: the feature bit
 129 */
 130static inline void __virtio_set_bit(struct virtio_device *vdev,
 131                                    unsigned int fbit)
 132{
 133        /* Did you forget to fix assumptions on max features? */
 134        if (__builtin_constant_p(fbit))
 135                BUILD_BUG_ON(fbit >= 64);
 136        else
 137                BUG_ON(fbit >= 64);
 138
 139        vdev->features |= BIT_ULL(fbit);
 140}
 141
 142/**
 143 * __virtio_clear_bit - helper to clear feature bits. For use by transports.
 144 * @vdev: the device
 145 * @fbit: the feature bit
 146 */
 147static inline void __virtio_clear_bit(struct virtio_device *vdev,
 148                                      unsigned int fbit)
 149{
 150        /* Did you forget to fix assumptions on max features? */
 151        if (__builtin_constant_p(fbit))
 152                BUILD_BUG_ON(fbit >= 64);
 153        else
 154                BUG_ON(fbit >= 64);
 155
 156        vdev->features &= ~BIT_ULL(fbit);
 157}
 158
 159/**
 160 * virtio_has_feature - helper to determine if this device has this feature.
 161 * @vdev: the device
 162 * @fbit: the feature bit
 163 */
 164static inline bool virtio_has_feature(const struct virtio_device *vdev,
 165                                      unsigned int fbit)
 166{
 167        if (fbit < VIRTIO_TRANSPORT_F_START)
 168                virtio_check_driver_offered_feature(vdev, fbit);
 169
 170        return __virtio_test_bit(vdev, fbit);
 171}
 172
 173/**
 174 * virtio_has_dma_quirk - determine whether this device has the DMA quirk
 175 * @vdev: the device
 176 */
 177static inline bool virtio_has_dma_quirk(const struct virtio_device *vdev)
 178{
 179        /*
 180         * Note the reverse polarity of the quirk feature (compared to most
 181         * other features), this is for compatibility with legacy systems.
 182         */
 183        return !virtio_has_feature(vdev, VIRTIO_F_ACCESS_PLATFORM);
 184}
 185
 186static inline
 187struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
 188                                        vq_callback_t *c, const char *n)
 189{
 190        vq_callback_t *callbacks[] = { c };
 191        const char *names[] = { n };
 192        struct virtqueue *vq;
 193        int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names, NULL,
 194                                         NULL);
 195        if (err < 0)
 196                return ERR_PTR(err);
 197        return vq;
 198}
 199
 200static inline
 201int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
 202                        struct virtqueue *vqs[], vq_callback_t *callbacks[],
 203                        const char * const names[],
 204                        struct irq_affinity *desc)
 205{
 206        return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL, desc);
 207}
 208
 209static inline
 210int virtio_find_vqs_ctx(struct virtio_device *vdev, unsigned nvqs,
 211                        struct virtqueue *vqs[], vq_callback_t *callbacks[],
 212                        const char * const names[], const bool *ctx,
 213                        struct irq_affinity *desc)
 214{
 215        return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, ctx,
 216                                      desc);
 217}
 218
 219/**
 220 * virtio_device_ready - enable vq use in probe function
 221 * @vdev: the device
 222 *
 223 * Driver must call this to use vqs in the probe function.
 224 *
 225 * Note: vqs are enabled automatically after probe returns.
 226 */
 227static inline
 228void virtio_device_ready(struct virtio_device *dev)
 229{
 230        unsigned status = dev->config->get_status(dev);
 231
 232        BUG_ON(status & VIRTIO_CONFIG_S_DRIVER_OK);
 233        dev->config->set_status(dev, status | VIRTIO_CONFIG_S_DRIVER_OK);
 234}
 235
 236static inline
 237const char *virtio_bus_name(struct virtio_device *vdev)
 238{
 239        if (!vdev->config->bus_name)
 240                return "virtio";
 241        return vdev->config->bus_name(vdev);
 242}
 243
 244/**
 245 * virtqueue_set_affinity - setting affinity for a virtqueue
 246 * @vq: the virtqueue
 247 * @cpu: the cpu no.
 248 *
 249 * Pay attention the function are best-effort: the affinity hint may not be set
 250 * due to config support, irq type and sharing.
 251 *
 252 */
 253static inline
 254int virtqueue_set_affinity(struct virtqueue *vq, const struct cpumask *cpu_mask)
 255{
 256        struct virtio_device *vdev = vq->vdev;
 257        if (vdev->config->set_vq_affinity)
 258                return vdev->config->set_vq_affinity(vq, cpu_mask);
 259        return 0;
 260}
 261
 262static inline
 263bool virtio_get_shm_region(struct virtio_device *vdev,
 264                           struct virtio_shm_region *region, u8 id)
 265{
 266        if (!vdev->config->get_shm_region)
 267                return false;
 268        return vdev->config->get_shm_region(vdev, region, id);
 269}
 270
 271static inline bool virtio_is_little_endian(struct virtio_device *vdev)
 272{
 273        return virtio_has_feature(vdev, VIRTIO_F_VERSION_1) ||
 274                virtio_legacy_is_little_endian();
 275}
 276
 277/* Memory accessors */
 278static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
 279{
 280        return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
 281}
 282
 283static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
 284{
 285        return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
 286}
 287
 288static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
 289{
 290        return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
 291}
 292
 293static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
 294{
 295        return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
 296}
 297
 298static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
 299{
 300        return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
 301}
 302
 303static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
 304{
 305        return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
 306}
 307
 308#define virtio_to_cpu(vdev, x) \
 309        _Generic((x), \
 310                __u8: (x), \
 311                __virtio16: virtio16_to_cpu((vdev), (x)), \
 312                __virtio32: virtio32_to_cpu((vdev), (x)), \
 313                __virtio64: virtio64_to_cpu((vdev), (x)) \
 314                )
 315
 316#define cpu_to_virtio(vdev, x, m) \
 317        _Generic((m), \
 318                __u8: (x), \
 319                __virtio16: cpu_to_virtio16((vdev), (x)), \
 320                __virtio32: cpu_to_virtio32((vdev), (x)), \
 321                __virtio64: cpu_to_virtio64((vdev), (x)) \
 322                )
 323
 324#define __virtio_native_type(structname, member) \
 325        typeof(virtio_to_cpu(NULL, ((structname*)0)->member))
 326
 327/* Config space accessors. */
 328#define virtio_cread(vdev, structname, member, ptr)                     \
 329        do {                                                            \
 330                typeof(((structname*)0)->member) virtio_cread_v;        \
 331                                                                        \
 332                might_sleep();                                          \
 333                /* Sanity check: must match the member's type */        \
 334                typecheck(typeof(virtio_to_cpu((vdev), virtio_cread_v)), *(ptr)); \
 335                                                                        \
 336                switch (sizeof(virtio_cread_v)) {                       \
 337                case 1:                                                 \
 338                case 2:                                                 \
 339                case 4:                                                 \
 340                        vdev->config->get((vdev),                       \
 341                                          offsetof(structname, member), \
 342                                          &virtio_cread_v,              \
 343                                          sizeof(virtio_cread_v));      \
 344                        break;                                          \
 345                default:                                                \
 346                        __virtio_cread_many((vdev),                     \
 347                                          offsetof(structname, member), \
 348                                          &virtio_cread_v,              \
 349                                          1,                            \
 350                                          sizeof(virtio_cread_v));      \
 351                        break;                                          \
 352                }                                                       \
 353                *(ptr) = virtio_to_cpu(vdev, virtio_cread_v);           \
 354        } while(0)
 355
 356/* Config space accessors. */
 357#define virtio_cwrite(vdev, structname, member, ptr)                    \
 358        do {                                                            \
 359                typeof(((structname*)0)->member) virtio_cwrite_v =      \
 360                        cpu_to_virtio(vdev, *(ptr), ((structname*)0)->member); \
 361                                                                        \
 362                might_sleep();                                          \
 363                /* Sanity check: must match the member's type */        \
 364                typecheck(typeof(virtio_to_cpu((vdev), virtio_cwrite_v)), *(ptr)); \
 365                                                                        \
 366                vdev->config->set((vdev), offsetof(structname, member), \
 367                                  &virtio_cwrite_v,                     \
 368                                  sizeof(virtio_cwrite_v));             \
 369        } while(0)
 370
 371/*
 372 * Nothing virtio-specific about these, but let's worry about generalizing
 373 * these later.
 374 */
 375#define virtio_le_to_cpu(x) \
 376        _Generic((x), \
 377                __u8: (u8)(x), \
 378                 __le16: (u16)le16_to_cpu(x), \
 379                 __le32: (u32)le32_to_cpu(x), \
 380                 __le64: (u64)le64_to_cpu(x) \
 381                )
 382
 383#define virtio_cpu_to_le(x, m) \
 384        _Generic((m), \
 385                 __u8: (x), \
 386                 __le16: cpu_to_le16(x), \
 387                 __le32: cpu_to_le32(x), \
 388                 __le64: cpu_to_le64(x) \
 389                )
 390
 391/* LE (e.g. modern) Config space accessors. */
 392#define virtio_cread_le(vdev, structname, member, ptr)                  \
 393        do {                                                            \
 394                typeof(((structname*)0)->member) virtio_cread_v;        \
 395                                                                        \
 396                might_sleep();                                          \
 397                /* Sanity check: must match the member's type */        \
 398                typecheck(typeof(virtio_le_to_cpu(virtio_cread_v)), *(ptr)); \
 399                                                                        \
 400                switch (sizeof(virtio_cread_v)) {                       \
 401                case 1:                                                 \
 402                case 2:                                                 \
 403                case 4:                                                 \
 404                        vdev->config->get((vdev),                       \
 405                                          offsetof(structname, member), \
 406                                          &virtio_cread_v,              \
 407                                          sizeof(virtio_cread_v));      \
 408                        break;                                          \
 409                default:                                                \
 410                        __virtio_cread_many((vdev),                     \
 411                                          offsetof(structname, member), \
 412                                          &virtio_cread_v,              \
 413                                          1,                            \
 414                                          sizeof(virtio_cread_v));      \
 415                        break;                                          \
 416                }                                                       \
 417                *(ptr) = virtio_le_to_cpu(virtio_cread_v);              \
 418        } while(0)
 419
 420#define virtio_cwrite_le(vdev, structname, member, ptr)                 \
 421        do {                                                            \
 422                typeof(((structname*)0)->member) virtio_cwrite_v =      \
 423                        virtio_cpu_to_le(*(ptr), ((structname*)0)->member); \
 424                                                                        \
 425                might_sleep();                                          \
 426                /* Sanity check: must match the member's type */        \
 427                typecheck(typeof(virtio_le_to_cpu(virtio_cwrite_v)), *(ptr)); \
 428                                                                        \
 429                vdev->config->set((vdev), offsetof(structname, member), \
 430                                  &virtio_cwrite_v,                     \
 431                                  sizeof(virtio_cwrite_v));             \
 432        } while(0)
 433
 434
 435/* Read @count fields, @bytes each. */
 436static inline void __virtio_cread_many(struct virtio_device *vdev,
 437                                       unsigned int offset,
 438                                       void *buf, size_t count, size_t bytes)
 439{
 440        u32 old, gen = vdev->config->generation ?
 441                vdev->config->generation(vdev) : 0;
 442        int i;
 443
 444        might_sleep();
 445        do {
 446                old = gen;
 447
 448                for (i = 0; i < count; i++)
 449                        vdev->config->get(vdev, offset + bytes * i,
 450                                          buf + i * bytes, bytes);
 451
 452                gen = vdev->config->generation ?
 453                        vdev->config->generation(vdev) : 0;
 454        } while (gen != old);
 455}
 456
 457static inline void virtio_cread_bytes(struct virtio_device *vdev,
 458                                      unsigned int offset,
 459                                      void *buf, size_t len)
 460{
 461        __virtio_cread_many(vdev, offset, buf, len, 1);
 462}
 463
 464static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset)
 465{
 466        u8 ret;
 467
 468        might_sleep();
 469        vdev->config->get(vdev, offset, &ret, sizeof(ret));
 470        return ret;
 471}
 472
 473static inline void virtio_cwrite8(struct virtio_device *vdev,
 474                                  unsigned int offset, u8 val)
 475{
 476        might_sleep();
 477        vdev->config->set(vdev, offset, &val, sizeof(val));
 478}
 479
 480static inline u16 virtio_cread16(struct virtio_device *vdev,
 481                                 unsigned int offset)
 482{
 483        __virtio16 ret;
 484
 485        might_sleep();
 486        vdev->config->get(vdev, offset, &ret, sizeof(ret));
 487        return virtio16_to_cpu(vdev, ret);
 488}
 489
 490static inline void virtio_cwrite16(struct virtio_device *vdev,
 491                                   unsigned int offset, u16 val)
 492{
 493        __virtio16 v;
 494
 495        might_sleep();
 496        v = cpu_to_virtio16(vdev, val);
 497        vdev->config->set(vdev, offset, &v, sizeof(v));
 498}
 499
 500static inline u32 virtio_cread32(struct virtio_device *vdev,
 501                                 unsigned int offset)
 502{
 503        __virtio32 ret;
 504
 505        might_sleep();
 506        vdev->config->get(vdev, offset, &ret, sizeof(ret));
 507        return virtio32_to_cpu(vdev, ret);
 508}
 509
 510static inline void virtio_cwrite32(struct virtio_device *vdev,
 511                                   unsigned int offset, u32 val)
 512{
 513        __virtio32 v;
 514
 515        might_sleep();
 516        v = cpu_to_virtio32(vdev, val);
 517        vdev->config->set(vdev, offset, &v, sizeof(v));
 518}
 519
 520static inline u64 virtio_cread64(struct virtio_device *vdev,
 521                                 unsigned int offset)
 522{
 523        __virtio64 ret;
 524
 525        __virtio_cread_many(vdev, offset, &ret, 1, sizeof(ret));
 526        return virtio64_to_cpu(vdev, ret);
 527}
 528
 529static inline void virtio_cwrite64(struct virtio_device *vdev,
 530                                   unsigned int offset, u64 val)
 531{
 532        __virtio64 v;
 533
 534        might_sleep();
 535        v = cpu_to_virtio64(vdev, val);
 536        vdev->config->set(vdev, offset, &v, sizeof(v));
 537}
 538
 539/* Conditional config space accessors. */
 540#define virtio_cread_feature(vdev, fbit, structname, member, ptr)       \
 541        ({                                                              \
 542                int _r = 0;                                             \
 543                if (!virtio_has_feature(vdev, fbit))                    \
 544                        _r = -ENOENT;                                   \
 545                else                                                    \
 546                        virtio_cread((vdev), structname, member, ptr);  \
 547                _r;                                                     \
 548        })
 549
 550/* Conditional config space accessors. */
 551#define virtio_cread_le_feature(vdev, fbit, structname, member, ptr)    \
 552        ({                                                              \
 553                int _r = 0;                                             \
 554                if (!virtio_has_feature(vdev, fbit))                    \
 555                        _r = -ENOENT;                                   \
 556                else                                                    \
 557                        virtio_cread_le((vdev), structname, member, ptr); \
 558                _r;                                                     \
 559        })
 560
 561#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
 562int arch_has_restricted_virtio_memory_access(void);
 563#else
 564static inline int arch_has_restricted_virtio_memory_access(void)
 565{
 566        return 0;
 567}
 568#endif /* CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS */
 569
 570#endif /* _LINUX_VIRTIO_CONFIG_H */
 571