{"id":2225265,"url":"http://patchwork.ozlabs.org/api/patches/2225265/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260420183920.3626389-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":"<20260420183920.3626389-2-zhipingz@meta.com>","list_archive_url":null,"date":"2026-04-20T18:39:15","name":"[v1,1/2] vfio: add callback to get tph info for dma-buf","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"3877fe15d71b75c3495020957cb3295ecb233b42","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/20260420183920.3626389-2-zhipingz@meta.com/mbox/","series":[{"id":500663,"url":"http://patchwork.ozlabs.org/api/series/500663/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=500663","date":"2026-04-20T18:39:14","name":"Retrieve TPH from dma-buf for PCIe P2P memory access","version":1,"mbox":"http://patchwork.ozlabs.org/series/500663/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2225265/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2225265/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-pci+bounces-52795-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=IXb6LQOt;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-52795-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=\"IXb6LQOt\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=67.231.145.42","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 sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fzvhV0k2Pz1yD4\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 04:51:06 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 1E2B43027B72\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 20 Apr 2026 18:45:44 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 7811B3B6347;\n\tMon, 20 Apr 2026 18:45:43 +0000 (UTC)","from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com\n [67.231.145.42])\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 6321C3B7741\n\tfor <linux-pci@vger.kernel.org>; Mon, 20 Apr 2026 18:45:40 +0000 (UTC)","from pps.filterd (m0109334.ppops.net [127.0.0.1])\n\tby mx0a-00082601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63K1C2Cb2527954\n\tfor <linux-pci@vger.kernel.org>; Mon, 20 Apr 2026 11:45:39 -0700","from mail.thefacebook.com ([163.114.134.16])\n\tby mx0a-00082601.pphosted.com (PPS) with ESMTPS id 4dm98etny9-5\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT)\n\tfor <linux-pci@vger.kernel.org>; Mon, 20 Apr 2026 11:45:39 -0700 (PDT)","from twshared18017.01.snb2.facebook.com (2620:10d:c085:108::4) by\n mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id\n 15.2.2562.37; Mon, 20 Apr 2026 18:45:36 +0000","by devbig259.ftw1.facebook.com (Postfix, from userid 664516)\n\tid 2485B113AA961; Mon, 20 Apr 2026 11:39:24 -0700 (PDT)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776710743; cv=none;\n b=WwFe05l12NtnRD33ptEQk1lqoJbntv1YJkbQJlO58QGfMEri8VItwYaiOcZ5esZzeeJznWxave3F3R6Px/KqnlZABAVtiXAEnQcrCWKMXeZPYIc+czhHnFaDzkigRNMEiNKmMgi0e9AAACkFVYNPm3JnjFmhvyQcp+Waxl3ai/c=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776710743; c=relaxed/simple;\n\tbh=5n4SJ3GN2MNA5BgVK5udG9cp10uEwFtVzwQ/EzmMOe0=;\n\th=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=gUYzm/EABBz14mJpWKQArdgIpNzKfAxNMTBlLeWFfhuyFYfaQP2QHw5pbcE33PXhtZ1YQ/qZitHKWNrK6Q0x6eTrqN31IoFKjn2arXWdyc/vhNMxEQP1p0zsVYEsgl4LjEY5+Dg2F9Tnk5+yEQuZCOtXXXFcGpRBWLEuRLf8ucw=","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=IXb6LQOt; arc=none smtp.client-ip=67.231.145.42","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=XhuZiiyrnopFqS0rKfTDKQudcjtEPD5wnNeB1aSoUSk=; b=IXb6LQOtkRlA\n\tc6H5k5+EYpIviOUfd4cUuKX2Yzyrl1hl+V5CbZ4uFDH63tg5XRQgl9Nc90K4ZAkP\n\tnrkHb04/0iul3QRoPacdSYaw3RjHiT16/Ki/9cT0sAy0MeamyhiCeo3ToMdkfhRE\n\t52QMEP6gF0cXqC2uvIwPxA7GFyWX/sPXWyW9M3QzDvr7/PQ6Xn+QJBeQtR6VNQH+\n\t6S4JBVzDQbk0erPceyfhX3MReGCjz63V476P76odP12l2Xb7pLCUKerOHLnQo3v+\n\tx6AspQpxCbv1VFnLNV9KDfXaFcH8D4NpcmnCtOIF2S5IA4WUdrhZOmXGKFyGzQpL\n\tVy1Z/i7NCA==","From":"Zhiping Zhang <zhipingz@meta.com>","To":"Stanislav Fomichev <sdf@meta.com>, Keith Busch <kbusch@kernel.org>","CC":"Jason Gunthorpe <jgg@ziepe.ca>, Leon Romanovsky <leon@kernel.org>,\n        Bjorn\n 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>, Yochai Cohen <yochai@nvidia.com>,\n        Yishai\n Hadas <yishaih@nvidia.com>, Zhiping Zhang <zhipingz@meta.com>","Subject":"[PATCH v1 1/2] vfio: add callback to get tph info for dma-buf","Date":"Mon, 20 Apr 2026 11:39:15 -0700","Message-ID":"<20260420183920.3626389-2-zhipingz@meta.com>","X-Mailer":"git-send-email 2.52.0","In-Reply-To":"<20260420183920.3626389-1-zhipingz@meta.com>","References":"<20260420183920.3626389-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-Authority-Analysis":"v=2.4 cv=ZK/nX37b c=1 sm=1 tr=0 ts=69e67453 cx=c_pps\n a=CB4LiSf2rd0gKozIdrpkBw==:117 a=CB4LiSf2rd0gKozIdrpkBw==:17\n a=A5OVakUREuEA:10 a=VkNPw1HP01LnGYTKEx00:22 a=7x6HtfJdh03M6CCDgxCd:22\n a=crHB47gyY4rKiduisYu9:22 a=VabnemYjAAAA:8 a=0e9SYv1gM71y3HGMkVkA:9\n a=gKebqoRLp9LExxC7YDUY:22","X-Proofpoint-ORIG-GUID":"Ozt1YwdGs5CdXN7MWYWnnIKq146IPRBW","X-Proofpoint-GUID":"Ozt1YwdGs5CdXN7MWYWnnIKq146IPRBW","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwNDIwMDE4MiBTYWx0ZWRfXzDKDqetqzh6s\n FNK+J+FWYgqcjwyoebj/rLK9m5HNcxEHozoXALaQW5T8/ZoHvujiX32q2zzzDlcK43DZsBR7QWQ\n MA9xO61g5f190iybGh8mAIUCXtOogkcHOSkReWmX0NVjCSqIfuV4m/TuuyaFe7iZUx8gxDL88tJ\n 9yQKB1z0I27jwHP1u5ni+gkj0AleeWwRSKAMMTst8InbqelCYNAJTduZunRLuIjH+nQSgCTGyuo\n 2Ar0bySlaV22cqjbu+SJGWLK0zToue7Eag2uZPinazLrWKWmIPEEMjMYFfhyRjt/vCOYopHdaAr\n eeqtwfQ0KTMh8tBeaqOrAAxkq3jlOkprglYlMcDFKSNNkZmnOPnV7FJ+HfhSFSHL1Rc2hLd+6Gu\n 5Ohb0tg7PNDt3J4eju8GXn8lgkq/U9nRn6k3DUE5y54jy2ipKy2/ViecadRCv5TXerg4J8UiMHB\n wataZ4Yt/yFwyli2tRg==","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-20_03,2026-04-20_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\nKeep the existing VFIO_DEVICE_FEATURE_DMA_BUF uAPI layout intact by\nusing a flag plus one extra trailing entries[] object for the optional\nTPH metadata. Rename the uAPI field dma_ranges to entries. The\nnr_ranges field remains the DMA range count; when VFIO_DMABUF_FLAG_TPH\nis set the kernel reads one extra entry beyond nr_ranges for the TPH\nmetadata.\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, make get_tph() return -EOPNOTSUPP.\n\nSigned-off-by: Zhiping Zhang <zhipingz@meta.com>\n---\n drivers/vfio/pci/vfio_pci_dmabuf.c | 62 +++++++++++++++++++++++-------\n include/linux/dma-buf.h            | 17 ++++++++\n include/uapi/linux/vfio.h          | 28 ++++++++++++--\n 3 files changed, 89 insertions(+), 18 deletions(-)","diff":"diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c\nindex b1d658b8f7b5..fdc05f9ab3ae 100644\n--- a/drivers/vfio/pci/vfio_pci_dmabuf.c\n+++ b/drivers/vfio/pci/vfio_pci_dmabuf.c\n@@ -17,6 +17,9 @@ struct vfio_pci_dma_buf {\n \tstruct phys_vec *phys_vec;\n \tstruct p2pdma_provider *provider;\n \tu32 nr_ranges;\n+\tu16 steering_tag;\n+\tu8 ph;\n+\tu8 tph_present : 1;\n \tu8 revoked : 1;\n };\n \n@@ -60,6 +63,22 @@ vfio_pci_dma_buf_map(struct dma_buf_attachment *attachment,\n \t\t\t\t       priv->size, dir);\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@@ -89,6 +108,7 @@ static const struct dma_buf_ops vfio_pci_dmabuf_ops = {\n \t.pin = vfio_pci_dma_buf_pin,\n \t.unpin = vfio_pci_dma_buf_unpin,\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@@ -211,7 +231,9 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n \t\t\t\t  size_t argsz)\n {\n \tstruct vfio_device_feature_dma_buf get_dma_buf = {};\n-\tstruct vfio_region_dma_range *dma_ranges;\n+\tbool tph_supplied;\n+\tu32 tph_index;\n+\tstruct vfio_region_dma_range *entries;\n \tDEFINE_DMA_BUF_EXPORT_INFO(exp_info);\n \tstruct vfio_pci_dma_buf *priv;\n \tsize_t length;\n@@ -228,7 +250,10 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n \tif (copy_from_user(&get_dma_buf, arg, sizeof(get_dma_buf)))\n \t\treturn -EFAULT;\n \n-\tif (!get_dma_buf.nr_ranges || get_dma_buf.flags)\n+\ttph_supplied = !!(get_dma_buf.flags & VFIO_DMABUF_FLAG_TPH);\n+\ttph_index = get_dma_buf.nr_ranges;\n+\tif (!get_dma_buf.nr_ranges ||\n+\t    (get_dma_buf.flags & ~VFIO_DMABUF_FLAG_TPH))\n \t\treturn -EINVAL;\n \n \t/*\n@@ -237,19 +262,21 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n \tif (get_dma_buf.region_index >= VFIO_PCI_ROM_REGION_INDEX)\n \t\treturn -ENODEV;\n \n-\tdma_ranges = memdup_array_user(&arg->dma_ranges, get_dma_buf.nr_ranges,\n-\t\t\t\t       sizeof(*dma_ranges));\n-\tif (IS_ERR(dma_ranges))\n-\t\treturn PTR_ERR(dma_ranges);\n+\tentries = memdup_array_user(&arg->entries,\n+\t\t\t\t    get_dma_buf.nr_ranges +\n+\t\t\t\t\t(tph_supplied ? 1 : 0),\n+\t\t\t\t    sizeof(*entries));\n+\tif (IS_ERR(entries))\n+\t\treturn PTR_ERR(entries);\n \n-\tret = validate_dmabuf_input(&get_dma_buf, dma_ranges, &length);\n+\tret = validate_dmabuf_input(&get_dma_buf, entries, &length);\n \tif (ret)\n-\t\tgoto err_free_ranges;\n+\t\tgoto err_free_entries;\n \n \tpriv = kzalloc_obj(*priv);\n \tif (!priv) {\n \t\tret = -ENOMEM;\n-\t\tgoto err_free_ranges;\n+\t\tgoto err_free_entries;\n \t}\n \tpriv->phys_vec = kzalloc_objs(*priv->phys_vec, get_dma_buf.nr_ranges);\n \tif (!priv->phys_vec) {\n@@ -260,15 +287,22 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n \tpriv->vdev = vdev;\n \tpriv->nr_ranges = get_dma_buf.nr_ranges;\n \tpriv->size = length;\n+\n+\tif (tph_supplied) {\n+\t\tpriv->steering_tag = entries[tph_index].tph.steering_tag;\n+\t\tpriv->ph = entries[tph_index].tph.ph;\n+\t\tpriv->tph_present = 1;\n+\t}\n+\n \tret = vdev->pci_ops->get_dmabuf_phys(vdev, &priv->provider,\n \t\t\t\t\t     get_dma_buf.region_index,\n-\t\t\t\t\t     priv->phys_vec, dma_ranges,\n+\t\t\t\t\t     priv->phys_vec, entries,\n \t\t\t\t\t     priv->nr_ranges);\n \tif (ret)\n \t\tgoto err_free_phys;\n \n-\tkfree(dma_ranges);\n-\tdma_ranges = NULL;\n+\tkfree(entries);\n+\tentries = NULL;\n \n \tif (!vfio_device_try_get_registration(&vdev->vdev)) {\n \t\tret = -ENODEV;\n@@ -311,8 +345,8 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,\n \tkfree(priv->phys_vec);\n err_free_priv:\n \tkfree(priv);\n-err_free_ranges:\n-\tkfree(dma_ranges);\n+err_free_entries:\n+\tkfree(entries);\n \treturn ret;\n }\n \ndiff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h\nindex 133b9e637b55..b0a79ccbe100 100644\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\nindex bb7b89330d35..a0bd24623c52 100644\n--- a/include/uapi/linux/vfio.h\n+++ b/include/uapi/linux/vfio.h\n@@ -1490,16 +1490,36 @@ struct vfio_device_feature_bus_master {\n  * open_flags are the typical flags passed to open(2), eg O_RDWR, O_CLOEXEC,\n  * etc. offset/length specify a slice of the region to create the dmabuf from.\n  * nr_ranges is the total number of (P2P DMA) ranges that comprise the dmabuf.\n+ * When VFIO_DMABUF_FLAG_TPH is set, entries[] contains one extra trailing\n+ * object after the nr_ranges DMA ranges carrying the TPH steering tag and\n+ * processing hint.\n  *\n- * flags should be 0.\n+ * flags should be 0 or VFIO_DMABUF_FLAG_TPH.\n  *\n  * Return: The fd number on success, -1 and errno is set on failure.\n  */\n #define VFIO_DEVICE_FEATURE_DMA_BUF 11\n \n+enum vfio_device_feature_dma_buf_flags {\n+\tVFIO_DMABUF_FLAG_TPH = 1 << 0,\n+};\n+\n+struct vfio_region_dma_tph {\n+\t__u16 steering_tag;\n+\t__u8 ph;\n+\t__u8 reserved;\n+\t__u32 reserved2;\n+};\n+\n struct vfio_region_dma_range {\n-\t__u64 offset;\n-\t__u64 length;\n+\tunion {\n+\t\t__u64 offset;\n+\t\tstruct vfio_region_dma_tph tph;\n+\t};\n+\tunion {\n+\t\t__u64 length;\n+\t\t__u64 reserved;\n+\t};\n };\n \n struct vfio_device_feature_dma_buf {\n@@ -1507,7 +1527,7 @@ struct vfio_device_feature_dma_buf {\n \t__u32\topen_flags;\n \t__u32   flags;\n \t__u32   nr_ranges;\n-\tstruct vfio_region_dma_range dma_ranges[] __counted_by(nr_ranges);\n+\tstruct vfio_region_dma_range entries[];\n };\n \n /* -------- API for Type1 VFIO IOMMU -------- */\n","prefixes":["v1","1/2"]}