On Mon, May 4, 2026 at 2:45 PM Alex Williamson <[email protected]> wrote: > > > > On Thu, 30 Apr 2026 13:06:56 -0700 > Zhiping Zhang <[email protected]> wrote: > > > Add a dma-buf callback that returns raw TPH metadata from the exporter > > so peer devices can reuse the steering tag and processing hint > > associated with a VFIO-exported buffer. > > > > Add a new VFIO_DEVICE_FEATURE_DMA_BUF_TPH ioctl that takes the fd from > > VFIO_DEVICE_FEATURE_DMA_BUF along with a steering tag and processing > > hint, validates the fd is a vfio-exported dma-buf belonging to this > > device, and stores the TPH values under memory_lock. This keeps the > > existing VFIO_DEVICE_FEATURE_DMA_BUF uAPI completely unchanged. > > > > The user sequences setting TPH on the dma-buf before the importer > > consumes it. > > > > Add an st_width parameter to get_tph() so the exporter can reject > > steering tags that exceed the consumer's supported width (8 vs 16 bit). > > When no TPH metadata was supplied, get_tph() returns -EOPNOTSUPP. > > > > Signed-off-by: Zhiping Zhang <[email protected]> > > The uAPI is better, but sashiko has some review comments[1] for you. > > Please also copy the kvm list for vfio related development. Thanks, > > Alex
Got it, thanks Alex. let me check sashiko's comments and post a new revision. i also copied [email protected] and will include in future revisions. Zhiping > > [1]https://urldefense.com/v3/__https://sashiko.dev/*/patchset/[email protected]__;Iw!!Bt8RZUm9aw!7glmqoMRhcdDwOgCAQuuEVqlhFJrh9bAYHXvicXPAO2M-k-NPwE_wFeUjVhe7EXbkXMd6g7eOe13$ > > > diff --git a/drivers/vfio/pci/vfio_pci_core.c > > b/drivers/vfio/pci/vfio_pci_core.c > > --- a/drivers/vfio/pci/vfio_pci_core.c > > +++ b/drivers/vfio/pci/vfio_pci_core.c > > @@ -1534,6 +1534,9 @@ int vfio_pci_core_ioctl_feature(struct vfio_device > > *device, u32 flags, > > return vfio_pci_core_feature_token(vdev, flags, arg, argsz); > > case VFIO_DEVICE_FEATURE_DMA_BUF: > > return vfio_pci_core_feature_dma_buf(vdev, flags, arg, argsz); > > + case VFIO_DEVICE_FEATURE_DMA_BUF_TPH: > > + return vfio_pci_core_feature_dma_buf_tph(vdev, flags, arg, > > + argsz); > > default: > > return -ENOTTY; > > } > > diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c > > b/drivers/vfio/pci/vfio_pci_dmabuf.c > > --- a/drivers/vfio/pci/vfio_pci_dmabuf.c > > +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c > > @@ -19,6 +19,9 @@ struct vfio_pci_dma_buf { > > u32 nr_ranges; > > struct kref kref; > > struct completion comp; > > + u16 steering_tag; > > + u8 ph; > > + u8 tph_present : 1; > > u8 revoked : 1; > > }; > > > > @@ -69,6 +72,22 @@ vfio_pci_dma_buf_map(struct dma_buf_attachment > > *attachment, > > return ret; > > } > > > > +static int vfio_pci_dma_buf_get_tph(struct dma_buf *dmabuf, u16 > > *steering_tag, > > + u8 *ph, u8 st_width) > > +{ > > + struct vfio_pci_dma_buf *priv = dmabuf->priv; > > + > > + if (!priv->tph_present) > > + return -EOPNOTSUPP; > > + > > + if (st_width < 16 && priv->steering_tag > ((1U << st_width) - 1)) > > + return -EINVAL; > > + > > + *steering_tag = priv->steering_tag; > > + *ph = priv->ph; > > + return 0; > > +} > > + > > static void vfio_pci_dma_buf_unmap(struct dma_buf_attachment *attachment, > > struct sg_table *sgt, > > enum dma_data_direction dir) > > @@ -101,6 +120,7 @@ static void vfio_pci_dma_buf_release(struct dma_buf > > *dmabuf) > > > > static const struct dma_buf_ops vfio_pci_dmabuf_ops = { > > .attach = vfio_pci_dma_buf_attach, > > + .get_tph = vfio_pci_dma_buf_get_tph, > > .map_dma_buf = vfio_pci_dma_buf_map, > > .unmap_dma_buf = vfio_pci_dma_buf_unmap, > > .release = vfio_pci_dma_buf_release, > > @@ -331,6 +351,55 @@ int vfio_pci_core_feature_dma_buf(struct > > vfio_pci_core_device *vdev, u32 flags, > > return ret; > > } > > > > +int vfio_pci_core_feature_dma_buf_tph(struct vfio_pci_core_device *vdev, > > + u32 flags, > > + struct vfio_device_feature_dma_buf_tph > > __user *arg, > > + size_t argsz) > > +{ > > + struct vfio_device_feature_dma_buf_tph set_tph; > > + struct vfio_pci_dma_buf *priv; > > + struct dma_buf *dmabuf; > > + int ret; > > + > > + ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_SET, > > + sizeof(set_tph)); > > + if (ret != 1) > > + return ret; > > + > > + if (copy_from_user(&set_tph, arg, sizeof(set_tph))) > > + return -EFAULT; > > + > > + if (set_tph.reserved) > > + return -EINVAL; > > + > > + dmabuf = dma_buf_get(set_tph.dmabuf_fd); > > + if (IS_ERR(dmabuf)) > > + return PTR_ERR(dmabuf); > > + > > + if (dmabuf->ops != &vfio_pci_dmabuf_ops) { > > + ret = -EINVAL; > > + goto out_put; > > + } > > + > > + priv = dmabuf->priv; > > + down_write(&vdev->memory_lock); > > + if (priv->vdev != vdev) { > > + ret = -EINVAL; > > + goto out_unlock; > > + } > > + > > + priv->steering_tag = set_tph.steering_tag; > > + priv->ph = set_tph.ph; > > + priv->tph_present = 1; > > + ret = 0; > > + > > +out_unlock: > > + up_write(&vdev->memory_lock); > > +out_put: > > + dma_buf_put(dmabuf); > > + return ret; > > +} > > + > > void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev, bool revoked) > > { > > struct vfio_pci_dma_buf *priv; > > diff --git a/drivers/vfio/pci/vfio_pci_priv.h > > b/drivers/vfio/pci/vfio_pci_priv.h > > --- a/drivers/vfio/pci/vfio_pci_priv.h > > +++ b/drivers/vfio/pci/vfio_pci_priv.h > > @@ -118,6 +118,10 @@ static inline bool vfio_pci_is_vga(struct pci_dev > > *pdev) > > int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 > > flags, > > struct vfio_device_feature_dma_buf __user > > *arg, > > size_t argsz); > > +int vfio_pci_core_feature_dma_buf_tph(struct vfio_pci_core_device *vdev, > > + u32 flags, > > + struct vfio_device_feature_dma_buf_tph > > __user *arg, > > + size_t argsz); > > void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_device *vdev); > > void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev, bool > > revoked); > > #else > > @@ -128,6 +132,13 @@ vfio_pci_core_feature_dma_buf(struct > > vfio_pci_core_device *vdev, u32 flags, > > { > > return -ENOTTY; > > } > > +static inline int > > +vfio_pci_core_feature_dma_buf_tph(struct vfio_pci_core_device *vdev, u32 > > flags, > > + struct vfio_device_feature_dma_buf_tph > > __user *arg, > > + size_t argsz) > > +{ > > + return -ENOTTY; > > +} > > static inline void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_device > > *vdev) > > { > > } > > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > > --- a/include/linux/dma-buf.h > > +++ b/include/linux/dma-buf.h > > @@ -113,6 +113,23 @@ struct dma_buf_ops { > > */ > > void (*unpin)(struct dma_buf_attachment *attach); > > > > + /** > > + * @get_tph: > > + * @dmabuf: DMA buffer for which to retrieve TPH metadata > > + * @steering_tag: Returns the raw TPH steering tag > > + * @ph: Returns the TPH processing hint > > + * @st_width: Consumer's supported steering tag width in bits (8 or > > 16) > > + * > > + * Return the TPH (TLP Processing Hints) metadata associated with this > > + * DMA buffer. Exporters that do not provide TPH metadata should > > return > > + * -EOPNOTSUPP. If the steering tag exceeds @st_width bits, return > > + * -EINVAL. > > + * > > + * This callback is optional. > > + */ > > + int (*get_tph)(struct dma_buf *dmabuf, u16 *steering_tag, u8 *ph, > > + u8 st_width); > > + > > /** > > * @map_dma_buf: > > * > > diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h > > --- a/include/uapi/linux/vfio.h > > +++ b/include/uapi/linux/vfio.h > > @@ -1534,6 +1534,28 @@ struct vfio_device_feature_dma_buf { > > */ > > #define VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2 12 > > > > +/** > > + * Upon VFIO_DEVICE_FEATURE_SET associate TPH (TLP Processing Hints) > > metadata > > + * with a vfio-exported dma-buf. The dma-buf must have been created by > > + * VFIO_DEVICE_FEATURE_DMA_BUF on this device. > > + * > > + * dmabuf_fd is the file descriptor returned by > > VFIO_DEVICE_FEATURE_DMA_BUF. > > + * steering_tag and ph are the raw TPH values that importing drivers > > should use > > + * when accessing the buffer. > > + * > > + * The user must set TPH on the dma-buf before the importer consumes it. > > + * > > + * Return: 0 on success, -errno on failure. > > + */ > > +#define VFIO_DEVICE_FEATURE_DMA_BUF_TPH 13 > > + > > +struct vfio_device_feature_dma_buf_tph { > > + __s32 dmabuf_fd; > > + __u16 steering_tag; > > + __u8 ph; > > + __u8 reserved; > > +}; > > + > > /* -------- API for Type1 VFIO IOMMU -------- */ > > > > /** >
