STRUCT VIRTIO_CONFIG_OPS(9)
π¦ 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: thevirtio_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: thevirtio_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: thevirtio_device. Returns the config generation counter. βget_statusβ read the status byte.vdev: thevirtio_device. Returns the status byte. π¦set_statusβ write the status byte.vdev: thevirtio_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: thevirtio_device.nvqs: the number of virtqueues to find.vqs: on success, includes new virtqueues.vqs_info: array ofvirtqueue_infostructures. Returns0on success or error status. πdel_vqsβ free virtqueues found byfind_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 thevring_interruptthat is called after it.vdev: thevirtio_device. πget_featuresβ get the array of feature bits for this device.vdev: thevirtio_device. Returns the first 64 feature bits. π₯get_extended_featuresβvdev: thevirtio_device. Returns the firstVIRTIO_FEATURES_BITSfeature bits (all we currently need). ngl, that's the vibe.finalize_featuresβ confirm what device features we'll be using.vdev: thevirtio_device. This sends the driver feature bits to the device: it can change thedev->featurebits if it wants. Note that despite the name this can be called any number of times. Returns0on success or error status. πbus_nameβ return the bus name associated with the device (optional).vdev: thevirtio_device. This returns a pointer to the bus name a lapci_namefrom 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. Returns0on success or error status.disable_vq_and_resetwill 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. Returns0on success or error status. Ifdisable_vq_and_resetis set, thenenable_vq_after_resetmust 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 ofget/set,get_status/set_status, orget_features/finalize_featuresare 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
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms