{"id":2231542,"url":"http://patchwork.ozlabs.org/api/patches/2231542/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260430200704.352228-2-zhipingz@meta.com/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260430200704.352228-2-zhipingz@meta.com>","list_archive_url":null,"date":"2026-04-30T20:06:56","name":"[v2,1/2] vfio: add dma-buf get_tph callback and DMA_BUF_TPH feature","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"6572f3cbfd8b558ee4d69e4420b8328b08df6a8d","submitter":{"id":92088,"url":"http://patchwork.ozlabs.org/api/people/92088/?format=json","name":"Zhiping Zhang","email":"zhipingz@meta.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260430200704.352228-2-zhipingz@meta.com/mbox/","series":[{"id":502373,"url":"http://patchwork.ozlabs.org/api/series/502373/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=502373","date":"2026-04-30T20:06:56","name":"vfio/dma-buf: add TPH support for peer-to-peer access","version":2,"mbox":"http://patchwork.ozlabs.org/series/502373/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2231542/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2231542/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-pci+bounces-53537-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=meta.com header.i=@meta.com header.a=rsa-sha256\n header.s=s2048-2025-q2 header.b=ce6O/wDv;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c15:e001:75::12fc:5321; helo=sin.lore.kernel.org;\n envelope-from=linux-pci+bounces-53537-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com\n header.b=\"ce6O/wDv\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=67.231.153.30","smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=meta.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=meta.com"],"Received":["from sin.lore.kernel.org (sin.lore.kernel.org\n [IPv6:2600:3c15:e001:75::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g650n4mZMz1yGq\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 06:11:37 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id 0429F3007B03\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 20:11:34 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id CB18C38A70C;\n\tThu, 30 Apr 2026 20:11:32 +0000 (UTC)","from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com\n [67.231.153.30])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F90F38AC96\n\tfor <linux-pci@vger.kernel.org>; Thu, 30 Apr 2026 20:11:30 +0000 (UTC)","from pps.filterd (m0528005.ppops.net [127.0.0.1])\n\tby mx0a-00082601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63UDBBNx518622\n\tfor <linux-pci@vger.kernel.org>; Thu, 30 Apr 2026 13:11:30 -0700","from maileast.thefacebook.com ([163.114.135.16])\n\tby mx0a-00082601.pphosted.com (PPS) with ESMTPS id 4dsf6p8rjn-6\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT)\n\tfor <linux-pci@vger.kernel.org>; Thu, 30 Apr 2026 13:11:29 -0700 (PDT)","from twshared26632.02.snb2.facebook.com (2620:10d:c0a8:1b::2d) by\n mail.thefacebook.com (2620:10d:c0a9:6f::237c) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id\n 15.2.2562.37; Thu, 30 Apr 2026 20:11:26 +0000","by devbig259.ftw1.facebook.com (Postfix, from userid 664516)\n\tid 919901B9B4FCA; Thu, 30 Apr 2026 13:07:05 -0700 (PDT)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777579892; cv=none;\n b=PO+YWvU0lFsE6uXYQ8vEr3Q4b65XCcxmrzDHMLG/jOsNWAxQ9XNslbDNpJNNDdMKNNUO0yN1KHgprPMcYOe3Bib0Yo5g2La/+17rutPfJH+QN4Dueno5il1QIAYgu2f2/8df8lwpVIXXbu0vtNeNsjzzoOWj0aNXnIYq+nllXe0=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777579892; c=relaxed/simple;\n\tbh=1wcWlRJMjxj0jHmYQzP8mnKcDdSGaqSElmHhBBtTbHg=;\n\th=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=a37BWaocFnBukWly92I3Xs5VzvbdmpOUM4srUGrJvnsTqIwjH5CMw8vSQ8tKiNA41CsmfI6El3730d8HeWDgce4Z/VMEZPMMm5KWwuiOf0hTjHNeANSDliDa9OPhx14AnLXIPV9fWF16iONEAeOyTAwDZ4vVnb3RqQ+ijnz4QNc=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=meta.com;\n spf=pass smtp.mailfrom=meta.com;\n dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com\n header.b=ce6O/wDv; arc=none smtp.client-ip=67.231.153.30","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=cc\n\t:content-transfer-encoding:content-type:date:from:in-reply-to\n\t:message-id:mime-version:references:subject:to; s=s2048-2025-q2;\n\t bh=XO4gDs/Vlu99NfyVjj4NXutxQm8yt30Ut2WY5+A6e1s=; b=ce6O/wDvLzBW\n\t0tXIMu+id8OHvF0uHfUJEwOb97wJkuDhA4Jx5PCEzqDTQR2hqn4xpolTHrydAvny\n\taA7QQDuMybLgvYqAhanYSC5TeaDxwBFN7bvU4dAqmpQLTld3yJppy4gUjUGw76pR\n\txRIH9rTbGSSMNCR6ZrxV3X015hkYR6ZROFEQ3keoqFWxHvRIpD+rkyLk97B2aOLh\n\tRTqmG+hy9lFWNT6thNGodRXaXBhQnVzftJmJwJZawTEAV4Itwium/iSkXfsLyPKx\n\tSlJnMqsDYqnP+6c/7SBWortbHIRJt3ZYhKZAtS11FszZkICU68F7oXyn3+tGCeHP\n\tvP9heifzgA==","From":"Zhiping Zhang <zhipingz@meta.com>","To":"Alex Williamson <alex@shazbot.org>, Jason Gunthorpe <jgg@ziepe.ca>,\n        Leon\n Romanovsky <leon@kernel.org>","CC":"Bjorn Helgaas <helgaas@kernel.org>, <linux-rdma@vger.kernel.org>,\n        <linux-pci@vger.kernel.org>, <netdev@vger.kernel.org>,\n        <dri-devel@lists.freedesktop.org>, Keith Busch <kbusch@kernel.org>,\n        Yochai\n Cohen <yochai@nvidia.com>, Yishai Hadas <yishaih@nvidia.com>,\n        Zhiping Zhang\n\t<zhipingz@meta.com>","Subject":"[PATCH v2 1/2] vfio: add dma-buf get_tph callback and DMA_BUF_TPH\n feature","Date":"Thu, 30 Apr 2026 13:06:56 -0700","Message-ID":"<20260430200704.352228-2-zhipingz@meta.com>","X-Mailer":"git-send-email 2.52.0","In-Reply-To":"<20260430200704.352228-1-zhipingz@meta.com>","References":"<20260430200704.352228-1-zhipingz@meta.com>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","X-FB-Internal":"Safe","Content-Type":"text/plain","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwNDMwMDIwOCBTYWx0ZWRfXwvAUVB2RA/kS\n uRRQf1PYTWbnQrtYxhGntk1k2tYlsxOnFEXkJA0AveVLfLK3zGLq/FJl8O6RA3ydeGSEihf8G4k\n 9o5wLnE/9OmGd22706cK9N09RhsKnupMtOo0UrFhvYiAewreRLrplw4xtgjuBnOcqqlC3XHHGom\n 28JS+Ddlkr1T9P1zgY4JJsDKE2AdN0rozgWgri1b/Z4Uz6n/vxVKCXwby1vOnB9AVLhDreAANeF\n vfpva15ZB5g//oFl+r82jvPGBugEkw4OYhkmcO75iORuzfbtpLQzqe0eKXYF1nUWxpfDsaFRIR6\n 7KKhsdcCQWe8cr1d02zJLKO4giOk646cMvm1CeVFOH9bFvot/1IJ/z3lF9aTSxcgcug93CloPEv\n 99UbPDKwNytAcHhBbPjfjr6BjMnmK2IXVzo1/Hyigk+fSxZNYfLmHdd2N+fceyT17dOM9nw4Zz6\n At8Jb5IBzRV5KyXLVgQ==","X-Authority-Analysis":"v=2.4 cv=Cfo4Irrl c=1 sm=1 tr=0 ts=69f3b771 cx=c_pps\n a=MfjaFnPeirRr97d5FC5oHw==:117 a=MfjaFnPeirRr97d5FC5oHw==:17\n a=A5OVakUREuEA:10 a=VkNPw1HP01LnGYTKEx00:22 a=7x6HtfJdh03M6CCDgxCd:22\n a=jCddH8ec0KUNCymVuxII:22 a=VabnemYjAAAA:8 a=I2VOSbTcSc4ADjQXWK4A:9\n a=gKebqoRLp9LExxC7YDUY:22","X-Proofpoint-ORIG-GUID":"OEL-3tay4h5wsnI1pTD1fZDxFGK8SmdT","X-Proofpoint-GUID":"OEL-3tay4h5wsnI1pTD1fZDxFGK8SmdT","X-Proofpoint-Virus-Version":"vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-30_05,2026-04-30_02,2025-10-01_01"},"content":"Add a dma-buf callback that returns raw TPH metadata from the exporter\nso peer devices can reuse the steering tag and processing hint\nassociated with a VFIO-exported buffer.\n\nAdd a new VFIO_DEVICE_FEATURE_DMA_BUF_TPH ioctl that takes the fd from\nVFIO_DEVICE_FEATURE_DMA_BUF along with a steering tag and processing\nhint, validates the fd is a vfio-exported dma-buf belonging to this\ndevice, and stores the TPH values under memory_lock. This keeps the\nexisting VFIO_DEVICE_FEATURE_DMA_BUF uAPI completely unchanged.\n\nThe user sequences setting TPH on the dma-buf before the importer\nconsumes it.\n\nAdd an st_width parameter to get_tph() so the exporter can reject\nsteering tags that exceed the consumer's supported width (8 vs 16 bit).\nWhen no TPH metadata was supplied, get_tph() returns -EOPNOTSUPP.\n\nSigned-off-by: Zhiping Zhang <zhipingz@meta.com>","diff":"diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c\n--- a/drivers/vfio/pci/vfio_pci_core.c\n+++ b/drivers/vfio/pci/vfio_pci_core.c\n@@ -1534,6 +1534,9 @@ int vfio_pci_core_ioctl_feature(struct vfio_device *device, u32 flags,\n \t\treturn vfio_pci_core_feature_token(vdev, flags, arg, argsz);\n \tcase VFIO_DEVICE_FEATURE_DMA_BUF:\n \t\treturn vfio_pci_core_feature_dma_buf(vdev, flags, arg, argsz);\n+\tcase VFIO_DEVICE_FEATURE_DMA_BUF_TPH:\n+\t\treturn vfio_pci_core_feature_dma_buf_tph(vdev, flags, arg,\n+\t\t\t\t\t\t\t argsz);\n \tdefault:\n \t\treturn -ENOTTY;\n \t}\ndiff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c\n--- a/drivers/vfio/pci/vfio_pci_dmabuf.c\n+++ b/drivers/vfio/pci/vfio_pci_dmabuf.c\n@@ -19,6 +19,9 @@ struct vfio_pci_dma_buf {\n \tu32 nr_ranges;\n \tstruct kref kref;\n \tstruct completion comp;\n+\tu16 steering_tag;\n+\tu8 ph;\n+\tu8 tph_present : 1;\n \tu8 revoked : 1;\n };\n \n@@ -69,6 +72,22 @@ vfio_pci_dma_buf_map(struct dma_buf_attachment *attachment,\n \treturn ret;\n }\n \n+static int vfio_pci_dma_buf_get_tph(struct dma_buf *dmabuf, u16 *steering_tag,\n+\t\t\t\t    u8 *ph, u8 st_width)\n+{\n+\tstruct vfio_pci_dma_buf *priv = dmabuf->priv;\n+\n+\tif (!priv->tph_present)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (st_width < 16 && priv->steering_tag > ((1U << st_width) - 1))\n+\t\treturn -EINVAL;\n+\n+\t*steering_tag = priv->steering_tag;\n+\t*ph = priv->ph;\n+\treturn 0;\n+}\n+\n static void vfio_pci_dma_buf_unmap(struct dma_buf_attachment *attachment,\n \t\t\t\t   struct sg_table *sgt,\n \t\t\t\t   enum dma_data_direction dir)\n@@ -101,6 +120,7 @@ static void vfio_pci_dma_buf_release(struct dma_buf *dmabuf)\n \n static const struct dma_buf_ops vfio_pci_dmabuf_ops = {\n \t.attach = vfio_pci_dma_buf_attach,\n+\t.get_tph = vfio_pci_dma_buf_get_tph,\n \t.map_dma_buf = vfio_pci_dma_buf_map,\n \t.unmap_dma_buf = vfio_pci_dma_buf_unmap,\n \t.release = vfio_pci_dma_buf_release,\n@@ -331,6 +351,55 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n \treturn ret;\n }\n \n+int vfio_pci_core_feature_dma_buf_tph(struct vfio_pci_core_device *vdev,\n+\t\t\t\t      u32 flags,\n+\t\t\t\t      struct vfio_device_feature_dma_buf_tph __user *arg,\n+\t\t\t\t      size_t argsz)\n+{\n+\tstruct vfio_device_feature_dma_buf_tph set_tph;\n+\tstruct vfio_pci_dma_buf *priv;\n+\tstruct dma_buf *dmabuf;\n+\tint ret;\n+\n+\tret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_SET,\n+\t\t\t\t sizeof(set_tph));\n+\tif (ret != 1)\n+\t\treturn ret;\n+\n+\tif (copy_from_user(&set_tph, arg, sizeof(set_tph)))\n+\t\treturn -EFAULT;\n+\n+\tif (set_tph.reserved)\n+\t\treturn -EINVAL;\n+\n+\tdmabuf = dma_buf_get(set_tph.dmabuf_fd);\n+\tif (IS_ERR(dmabuf))\n+\t\treturn PTR_ERR(dmabuf);\n+\n+\tif (dmabuf->ops != &vfio_pci_dmabuf_ops) {\n+\t\tret = -EINVAL;\n+\t\tgoto out_put;\n+\t}\n+\n+\tpriv = dmabuf->priv;\n+\tdown_write(&vdev->memory_lock);\n+\tif (priv->vdev != vdev) {\n+\t\tret = -EINVAL;\n+\t\tgoto out_unlock;\n+\t}\n+\n+\tpriv->steering_tag = set_tph.steering_tag;\n+\tpriv->ph = set_tph.ph;\n+\tpriv->tph_present = 1;\n+\tret = 0;\n+\n+out_unlock:\n+\tup_write(&vdev->memory_lock);\n+out_put:\n+\tdma_buf_put(dmabuf);\n+\treturn ret;\n+}\n+\n void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev, bool revoked)\n {\n \tstruct vfio_pci_dma_buf *priv;\ndiff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h\n--- a/drivers/vfio/pci/vfio_pci_priv.h\n+++ b/drivers/vfio/pci/vfio_pci_priv.h\n@@ -118,6 +118,10 @@ static inline bool vfio_pci_is_vga(struct pci_dev *pdev)\n int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n \t\t\t\t  struct vfio_device_feature_dma_buf __user *arg,\n \t\t\t\t  size_t argsz);\n+int vfio_pci_core_feature_dma_buf_tph(struct vfio_pci_core_device *vdev,\n+\t\t\t\t      u32 flags,\n+\t\t\t\t      struct vfio_device_feature_dma_buf_tph __user *arg,\n+\t\t\t\t      size_t argsz);\n void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_device *vdev);\n void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev, bool revoked);\n #else\n@@ -128,6 +132,13 @@ vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n {\n \treturn -ENOTTY;\n }\n+static inline int\n+vfio_pci_core_feature_dma_buf_tph(struct vfio_pci_core_device *vdev, u32 flags,\n+\t\t\t\t  struct vfio_device_feature_dma_buf_tph __user *arg,\n+\t\t\t\t  size_t argsz)\n+{\n+\treturn -ENOTTY;\n+}\n static inline void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_device *vdev)\n {\n }\ndiff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h\n--- a/include/linux/dma-buf.h\n+++ b/include/linux/dma-buf.h\n@@ -113,6 +113,23 @@ struct dma_buf_ops {\n \t */\n \tvoid (*unpin)(struct dma_buf_attachment *attach);\n \n+\t/**\n+\t * @get_tph:\n+\t * @dmabuf: DMA buffer for which to retrieve TPH metadata\n+\t * @steering_tag: Returns the raw TPH steering tag\n+\t * @ph: Returns the TPH processing hint\n+\t * @st_width: Consumer's supported steering tag width in bits (8 or 16)\n+\t *\n+\t * Return the TPH (TLP Processing Hints) metadata associated with this\n+\t * DMA buffer. Exporters that do not provide TPH metadata should return\n+\t * -EOPNOTSUPP. If the steering tag exceeds @st_width bits, return\n+\t * -EINVAL.\n+\t *\n+\t * This callback is optional.\n+\t */\n+\tint (*get_tph)(struct dma_buf *dmabuf, u16 *steering_tag, u8 *ph,\n+\t\t       u8 st_width);\n+\n \t/**\n \t * @map_dma_buf:\n \t *\ndiff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h\n--- a/include/uapi/linux/vfio.h\n+++ b/include/uapi/linux/vfio.h\n@@ -1534,6 +1534,28 @@ struct vfio_device_feature_dma_buf {\n  */\n #define VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2  12\n \n+/**\n+ * Upon VFIO_DEVICE_FEATURE_SET associate TPH (TLP Processing Hints) metadata\n+ * with a vfio-exported dma-buf. The dma-buf must have been created by\n+ * VFIO_DEVICE_FEATURE_DMA_BUF on this device.\n+ *\n+ * dmabuf_fd is the file descriptor returned by VFIO_DEVICE_FEATURE_DMA_BUF.\n+ * steering_tag and ph are the raw TPH values that importing drivers should use\n+ * when accessing the buffer.\n+ *\n+ * The user must set TPH on the dma-buf before the importer consumes it.\n+ *\n+ * Return: 0 on success, -errno on failure.\n+ */\n+#define VFIO_DEVICE_FEATURE_DMA_BUF_TPH 13\n+\n+struct vfio_device_feature_dma_buf_tph {\n+\t__s32\tdmabuf_fd;\n+\t__u16\tsteering_tag;\n+\t__u8\tph;\n+\t__u8\treserved;\n+};\n+\n /* -------- API for Type1 VFIO IOMMU -------- */\n \n /**\n","prefixes":["v2","1/2"]}