STRUCT VIRTIO_CONFIG_OPS(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ¦‹ struct virtio_config_ops(9) πŸ¦‹

okay bestie, welcome to the Kernel API Manual page for struct virtio_config_ops β€” yes it's a whole struct of function pointers and yes it's lowkey the main character of virtio device configuration. grab a strawberry drink, we're doing this πŸ’…


✨ NAME ✨

struct virtio_config_ops β€” operations for configuring a virtio device πŸŽ€


🌸 SYNOPSIS 🌸

struct virtio_config_ops {
    void (*get)(struct virtio_device *vdev, unsigned offset, void *buf,
unsigned len);
    void (*set)(struct virtio_device *vdev, unsigned offset, const void
*buf, unsigned len);
    u32 (*generation)(struct virtio_device *vdev);
    u8 (*get_status)(struct virtio_device *vdev);
    void (*set_status)(struct virtio_device *vdev, u8 status);
    void (*reset)(struct virtio_device *vdev);
    int (*find_vqs)(struct virtio_device *vdev, unsigned int nvqs,
struct virtqueue *vqs[], struct virtqueue_info vqs_info[], struct
irq_affinity *desc);
    void (*del_vqs)(struct virtio_device *);
    void (*synchronize_cbs)(struct virtio_device *);
    u64 (*get_features)(struct virtio_device *vdev);
    void (*get_extended_features)(struct virtio_device *vdev, u64
*features);
    int (*finalize_features)(struct virtio_device *vdev);
    const char *(*bus_name)(struct virtio_device *vdev);
    int (*set_vq_affinity)(struct virtqueue *vq, const struct cpumask
*cpu_mask);
    const struct cpumask *(*get_vq_affinity)(struct virtio_device *vdev,
int index);
    bool (*get_shm_region)(struct virtio_device *vdev, struct
virtio_shm_region *region, u8 id);
    int (*disable_vq_and_reset)(struct virtqueue *vq);
    int (*enable_vq_after_reset)(struct virtqueue *vq);
 };

πŸ’œ Members πŸ’œ

  • get β€” read the value of a configuration field, fr fr. vdev: the virtio_device. offset: the offset of the configuration field. buf: the buffer to write the field value into. len: the length of the buffer. 🫢
  • set β€” write the value of a configuration field. vdev: the virtio_device. offset: the offset of the configuration field. buf: the buffer to read the field value from. len: the length of the buffer. ✨
  • generation β€” config generation counter, and it's optional btw. vdev: the virtio_device. Returns the config generation counter. ⭐
  • get_status β€” read the status byte. vdev: the virtio_device. Returns the status byte. πŸ¦‹
  • set_status β€” write the status byte. vdev: the virtio_device. status: the new status byte. πŸ’…
  • reset β€” reset the device. vdev: the virtio device. After this, status and feature negotiation must be done again. And listen πŸ‘‘: the device must not be reset from its vq/config callbacks, or in parallel with being added/removed. like, do not do that.
  • find_vqs β€” find virtqueues and instantiate them, iconic behaviour honestly. vdev: the virtio_device. nvqs: the number of virtqueues to find. vqs: on success, includes new virtqueues. vqs_info: array of virtqueue_info structures. Returns 0 on success or error status. πŸ’–
  • del_vqs β€” free virtqueues found by find_vqs, the cleanup arc 🧹
  • synchronize_cbs β€” synchronize with the virtqueue callbacks (optional!). The function guarantees that all memory operations on the queue before it are visible to the vring_interrupt that is called after it. vdev: the virtio_device. 🌈
  • get_features β€” get the array of feature bits for this device. vdev: the virtio_device. Returns the first 64 feature bits. πŸ”₯
  • get_extended_features β€” vdev: the virtio_device. Returns the first VIRTIO_FEATURES_BITS feature bits (all we currently need). ngl, that's the vibe.
  • finalize_features β€” confirm what device features we'll be using. vdev: the virtio_device. This sends the driver feature bits to the device: it can change the dev->feature bits if it wants. Note that despite the name this can be called any number of times. Returns 0 on success or error status. πŸ™ˆ
  • bus_name β€” return the bus name associated with the device (optional). vdev: the virtio_device. This returns a pointer to the bus name a la pci_name from which the caller can then copy. πŸŽ€
  • set_vq_affinity β€” set the affinity for a virtqueue (optional). πŸ’«
  • get_vq_affinity β€” get the affinity for a virtqueue (optional). πŸ’«
  • get_shm_region β€” get a shared memory region based on the index. 🌸
  • disable_vq_and_reset β€” reset a queue individually (optional). vq: the virtqueue. Returns 0 on success or error status. disable_vq_and_reset will guarantee that the callbacks are disabled and synchronized. Except for the callback, the caller should guarantee that the vring is not accessed by any functions of virtqueue. 🫑
  • enable_vq_after_reset β€” enable a reset queue. vq: the virtqueue. Returns 0 on success or error status. If disable_vq_and_reset is set, then enable_vq_after_reset must also be set β€” they're a package deal bestie, no cap. πŸ’€

⭐ Note ⭐

Do not assume that a transport implements all of the operations getting/setting a value as a simple read/write! Generally speaking, any of get/set, get_status/set_status, or get_features/finalize_features are NOT safe to be called from an atomic context. 😭 read that again. it's giving "danger", it's giving "respect the caveat".

🌈 SEE ALSO 🌈

Kernel file ./include/linux/virtio_config.h β€” plus these besties: struct virtqueue_info(9), struct virtio_map_ops(9), __virtio_test_bit(9), __virtio_set_bit(9), __virtio_clear_bit(9), virtio_has_feature(9), virtio_has_dma_quirk(9), virtio_synchronize_cbs(9), virtio_device_ready(9), virtqueue_set_affinity(9).


okay that's the whole page, you ate that πŸ’… this was served fresh from ./include/linux, dated October 2026, in the struct virtio_config_ops(9) era β€” mwah, go read the source, ily, bye πŸŽ€πŸ¦‹πŸ’–

πŸ“¦ where this page comes from