STRUCT VDPA_CONFIG_OPS(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ struct vdpa_config_ops(9) ✨

okay bestie, so this is the kernel API manual page for struct vdpa_config_ops β€” literally the whole blueprint for how you configure a vDPA device. it's giving "backstage pass to the virtio universe" and honestly? we're obsessed. πŸ’–


πŸ¦‹ SYNOPSIS πŸ¦‹

like, here's the whole struct, no cap, every field exactly as it is:

struct vdpa_config_ops {
    int (*set_vq_address)(struct vdpa_device *vdev, u16 idx, u64
desc_area, u64 driver_area, u64 device_area);
    void (*set_vq_num)(struct vdpa_device *vdev, u16 idx, u32 num);
    void (*kick_vq)(struct vdpa_device *vdev, u16 idx);
    void (*kick_vq_with_data)(struct vdpa_device *vdev, u32 data);
    void (*set_vq_cb)(struct vdpa_device *vdev, u16 idx, struct
vdpa_callback *cb);
    void (*set_vq_ready)(struct vdpa_device *vdev, u16 idx, bool ready);
    bool (*get_vq_ready)(struct vdpa_device *vdev, u16 idx);
    int (*set_vq_state)(struct vdpa_device *vdev, u16 idx, const struct
vdpa_vq_state *state);
    int (*get_vq_state)(struct vdpa_device *vdev, u16 idx, struct
vdpa_vq_state *state);
    int (*get_vendor_vq_stats)(struct vdpa_device *vdev, u16 idx, struct
sk_buff *msg, struct netlink_ext_ack *extack);
    struct vdpa_notification_area (*get_vq_notification)(struct
vdpa_device *vdev, u16 idx);
    int (*get_vq_irq)(struct vdpa_device *vdev, u16 idx);
    u16 (*get_vq_size)(struct vdpa_device *vdev, u16 idx);
    u32 (*get_vq_align)(struct vdpa_device *vdev);
    u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);
    u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx);
    u64 (*get_device_features)(struct vdpa_device *vdev);
    u64 (*get_backend_features)(const struct vdpa_device *vdev);
    int (*set_driver_features)(struct vdpa_device *vdev, u64 features);
    u64 (*get_driver_features)(struct vdpa_device *vdev);
    void (*set_config_cb)(struct vdpa_device *vdev, struct vdpa_callback
*cb);
    u16 (*get_vq_num_max)(struct vdpa_device *vdev);
    u16 (*get_vq_num_min)(struct vdpa_device *vdev);
    u32 (*get_device_id)(struct vdpa_device *vdev);
    u32 (*get_vendor_id)(struct vdpa_device *vdev);
    u8 (*get_status)(struct vdpa_device *vdev);
    void (*set_status)(struct vdpa_device *vdev, u8 status);
    int (*reset)(struct vdpa_device *vdev);
    int (*compat_reset)(struct vdpa_device *vdev, u32 flags);
  #define VDPA_RESET_F_CLEAN_MAP 1;
    int (*suspend)(struct vdpa_device *vdev);
    int (*resume)(struct vdpa_device *vdev);
    size_t (*get_config_size)(struct vdpa_device *vdev);
    void (*get_config)(struct vdpa_device *vdev, unsigned int offset,
void *buf, unsigned int len);
    void (*set_config)(struct vdpa_device *vdev, unsigned int offset,
const void *buf, unsigned int len);
    u32 (*get_generation)(struct vdpa_device *vdev);
    struct vdpa_iova_range (*get_iova_range)(struct vdpa_device *vdev);
    int (*set_vq_affinity)(struct vdpa_device *vdev, u16 idx, const
struct cpumask *cpu_mask);
    const struct cpumask *(*get_vq_affinity)(struct vdpa_device *vdev,
u16 idx);
    int (*set_map)(struct vdpa_device *vdev, unsigned int asid, struct
vhost_iotlb *iotlb);
    int (*dma_map)(struct vdpa_device *vdev, unsigned int asid, u64
iova, u64 size, u64 pa, u32 perm, void *opaque);
    int (*dma_unmap)(struct vdpa_device *vdev, unsigned int asid, u64
iova, u64 size);
    int (*reset_map)(struct vdpa_device *vdev, unsigned int asid);
    int (*set_group_asid)(struct vdpa_device *vdev, unsigned int group,
unsigned int asid);
    union virtio_map (*get_vq_map)(struct vdpa_device *vdev, u16 idx);
    int (*bind_mm)(struct vdpa_device *vdev, struct mm_struct *mm);
    void (*unbind_mm)(struct vdpa_device *vdev);
    void (*free)(struct vdpa_device *vdev);
   };

like, that's a lot of function pointers, and every single one is a whole mood. let's get into it. πŸ‘‘


🌸 Members 🌸

so here's the tea on every single member β€” bestie, grab a snack, this is a long one:

  • set_vq_address β€” sets the address of the virtqueue. literally where it lives. iconic. 🏠
  • set_vq_num β€” sets the size of the virtqueue. how many can fit, basically.
  • kick_vq β€” kicks the virtqueue. wake it up, it's go time. πŸ’…
  • kick_vq_with_data β€” kicks the virtqueue AND supplies extra data. key detail: only if VIRTIO_F_NOTIFICATION_DATA is negotiated, so don't try it otherwise, bestie.
  • set_vq_cb β€” sets the interrupt callback function for a virtqueue. it's giving "call me when something happens" energy. πŸ“ž
  • set_vq_ready β€” sets ready status for a virtqueue. are we ready or not??
  • get_vq_ready β€” gets ready status for a virtqueue. the vibe check, essentially.
  • set_vq_state β€” sets the state for a virtqueue.
  • get_vq_state β€” gets the state for a virtqueue.
  • get_vendor_vq_stats β€” gets the vendor statistics of a device. all the numbers, slay. πŸ“Š
  • get_vq_notification β€” gets the notification area for a virtqueue. this one's optional. ✨
  • get_vq_irq β€” gets the irq number of a virtqueue. optional, BUT β€” and this is important β€” it must be implemented if you require vq irq offloading. no cap. 🚨
  • get_vq_size β€” gets the size of a specific virtqueue. optional.
  • get_vq_align β€” gets the virtqueue align requirement for the device. it's giving alignment everything. πŸ“
  • get_vq_group β€” gets the group id for a specific virtqueue. optional.
  • get_vq_desc_group β€” gets the group id for the descriptor table of a specific virtqueue. optional.
  • get_device_features β€” gets the virtio features supported by the device. the whole feature set, periodt.
  • get_backend_features β€” gets parent-specific backend features. optional. returns the vdpa features supported by the device.
  • set_driver_features β€” sets the virtio features supported by the driver.
  • get_driver_features β€” gets the virtio driver features in action. πŸ”₯
  • set_config_cb β€” sets the config interrupt callback.
  • get_vq_num_max β€” gets the max size of the virtqueue. the ceiling, bestie.
  • get_vq_num_min β€” gets the min size of the virtqueue. optional.
  • get_device_id β€” gets the virtio device id.
  • get_vendor_id β€” gets the id for the vendor that provides this device. who made you?? πŸ’β€β™€οΈ
  • get_status β€” gets the device status.
  • set_status β€” sets the device status.
  • reset β€” resets the device. the classic "have you tried turning it off and on again" but make it kernel. πŸ”„
  • compat_reset β€” resets the device with compatibility quirks to accommodate older userspace. okay this one's a whole saga: it's only needed by a parent driver which used to have bogus reset behaviour, and has to maintain such behaviour for compatibility with older userspace. historically, a compliant driver only has to implement .reset; historically a non-compliant driver should implement both. iykyk. 😭
  • suspend β€” suspends the device. optional. nap time. 😴
  • resume β€” resumes the device. optional. wakey wakey.
  • get_config_size β€” gets the size of the configuration space β€” and this includes fields that are conditional on feature bits, so it's not just a simple number, bestie.
  • get_config β€” reads from the device-specific configuration space.
  • set_config β€” writes to the device-specific configuration space.
  • get_generation β€” gets device config generation. optional.
  • get_iova_range β€” gets the supported iova range. optional.
  • set_vq_affinity β€” sets the affinity of a virtqueue. optional.
  • get_vq_affinity β€” gets the affinity of a virtqueue. optional.
  • set_map β€” sets the device memory mapping. optional. needed for a device that is using device-specific DMA translation (on-chip IOMMU). πŸ—ΊοΈ
  • dma_map β€” maps an area of PA to IOVA. optional. needed for a device that is using device-specific DMA translation (on-chip IOMMU) and prefers incremental map.
  • dma_unmap β€” unmaps an area of IOVA. optional but must be implemented with dma_map. needed for a device that is using device-specific DMA translation (on-chip IOMMU) and prefers incremental unmap. like they're a package deal, fr fr.
  • reset_map β€” resets the device memory mapping to the default state. optional. needed for devices that are using device-specific DMA translation and prefer mapping to be decoupled from the virtio life cycle β€” meaning the device .reset op does not reset mapping. important distinction, don't forget it. πŸ’€
  • set_group_asid β€” sets the address space identifier for a virtqueue group. optional. ⚠️ but the caller must prevent this from being executed concurrently with set_status. that's a hard requirement, not a suggestion.
  • get_vq_map β€” gets the map metadata for a specific virtqueue. optional.
  • bind_mm β€” binds the device to a specific address space so the vDPA framework can use VA when this callback is implemented. optional.
  • unbind_mm β€” unbinds the device from the address space that was bound using the bind_mm callback. optional.
  • free β€” frees resources that belong to vDPA. optional.

πŸŽ€ Note πŸŽ€

okay so this is the rule, bestie, listen up: vDPA device drivers are required to implement all of the operations unless it's specifically mentioned to be optional in the list above. so if you skipped one that wasn't marked optional, that's not slay behavior. do better. πŸ’…


🌈 SEE ALSO 🌈

  • Kernel file ./include/linux/vdpa.h
  • struct vdpa_callback(9)
  • struct vdpa_notification_area(9)
  • struct vdpa_vq_state_split(9)
  • struct vdpa_vq_state_packed(9)
  • struct vdpa_device(9)
  • struct vdpa_iova_range(9)
  • struct vdpa_map_file(9)
  • vdpa_alloc_device(9)
  • struct vdpa_driver(9)
  • struct vdpa_mgmtdev_ops(9)
  • struct vdpa_mgmt_dev(9)

and that's the whole page, bestie! every member, every optional flag, every compatibility quirk, all preserved and accounted for. we ate and left no crumbs. 🫢

this page is from ./include/linux, dated October 2026, and it's the struct vdpa_config_ops(9) page. mwah, go configure some vDPA devices, you've got this. πŸ’–πŸ¦‹βœ¨

πŸ“¦ where this page comes from