mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ankit Agrawal <ankita@nvidia.com>
To: <linux-cxl@vger.kernel.org>, <linux-pci@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Cc: <dave@stgolabs.net>, <jic23@kernel.org>, <dave.jiang@intel.com>,
	<alison.schofield@intel.com>, <vishal.l.verma@intel.com>,
	<jgg@nvidia.com>, <aneesh.kumar@kernel.org>, <aik@amd.com>,
	<yilun.xu@linux.intel.com>, <iweiny@kernel.org>,
	<ming.li@zohomail.com>, <icheng@nvidia.com>,
	<bhelgaas@google.com>, <smadhavan@nvidia.com>,
	<ankita@nvidia.com>, <ilpo.jarvinen@linux.intel.com>,
	<Smita.KoralahalliChannabasappa@amd.com>,
	<andriy.shevchenko@linux.intel.com>, <linux-coco@lists.linux.dev>
Subject: [RFC PATCH 4/4] PCI/TSM: Support multiple coherent ranges via coh_idx
Date: Mon, 5 Oct 2026 09:02:52 +0200	[thread overview]
Message-ID: <20261005070252.84810-5-ankita@nvidia.com> (raw)
In-Reply-To: <20261005070252.84810-1-ankita@nvidia.com>

Devices with multiple decoders can report more than one coherent
window in a single interface report. Generalize the single
0xffff sentinel into a small id space:
PCI_TSM_DEVIF_REPORT_MMIO_RANGE_ID_TO_COH_IDX() treats any range id in
the top PCI_CXL_MAX_COHERENT_RANGES values (counting down from ~0) as
a coherent range index coh_idx. This keeps id 0xffff (~0) backward
compatible with the single-range case (coh_idx 0) while allowing ~1,
~2, and so on for additional windows.

Only id 0xffff (~0) is spec-defined: Arm RME System Architecture
(DEN0129) section B2.3.5.2 reserves range ID 0xFFFF for a device's
region range. ~1, ~2, and so on are this tree's own extension of that
idea, invented to cover multi-range reporting.

Use coh_idx through pci_tsm_coherent_range() to select the coh_idx
entry of pdev->coh_resource[], the precommitted-decoder snapshot and
relax pci_tsm_mmio_alloc() to accept more than one coherent region.
The coherent-range entries follow all BAR entries in the report
and allow multiple trailing coherent ranges.

Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
Assisted-by: Claude:sonnet-5
---
 drivers/pci/tsm.c | 78 ++++++++++++++++++++++++++++-------------------
 1 file changed, 46 insertions(+), 32 deletions(-)

diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c
index 1d736b606a7c..b4f18a7c7187 100644
--- a/drivers/pci/tsm.c
+++ b/drivers/pci/tsm.c
@@ -1031,7 +1031,14 @@ EXPORT_SYMBOL_GPL(pci_tsm_mmio_teardown);
 #define PCI_TSM_DEVIF_REPORT_MMIO_ATTR_IS_NON_TEE BIT(2)
 #define PCI_TSM_DEVIF_REPORT_MMIO_ATTR_IS_UPDATABLE BIT(3)
 #define PCI_TSM_DEVIF_REPORT_MMIO_ATTR_RANGE_ID GENMASK(31, 16)
-#define PCI_TSM_DEVIF_REPORT_MMIO_RANGE_ID_COHERENT 0xffff
+
+/*
+ * Only id ~0 (0xffff) is spec-defined (Arm RME DEN0129 section B2.3.5.2);
+ * ~1, ~2, etc. extend it for multi-range reporting: id ~N selects coherent
+ * window N, keeping coherent ids disjoint from BAR ids
+ * (0..PCI_STD_NUM_BARS-1) without a separate flag.
+ */
+#define PCI_TSM_DEVIF_REPORT_MMIO_RANGE_ID_TO_COH_IDX(id) ((u16)~(id))
 
 /* An interface report 'pfn' is 4K in size */
 struct pci_tsm_devif_mmio {
@@ -1052,37 +1059,39 @@ struct pci_tsm_devif_report {
 
 #ifdef CONFIG_CXL_RESET
 /*
- * pci_tsm_coherent_range() - resolve the device's coherent CXL window
+ * pci_tsm_coherent_range() - resolve the device coherent CXL window
  * @pdev: device owner of the reported ranges
+ * @coh_idx: which coherent range to resolve, per
+ *	     %PCI_TSM_DEVIF_REPORT_MMIO_RANGE_ID_TO_COH_IDX()
  * @out_base: host physical (guest IPA) base of the coherent window
  * @out_size: size of the coherent window
  *
- * The coherent range carries no BAR number, so its address comes from
- * pdev->coh_resource[], a pre-driver-bind snapshot of committed CXL HDM
- * decoders.
+ * Each @coh_idx names one of the device coherent (CXL) windows. It carries
+ * no BAR number and so its address comes from pdev->coh_resource[@coh_idx],
+ * which is a snapshot of committed CXL HDM decoders regions.
  *
- * Return: 0 with *@out_base / *@out_size set from the first populated entry,
- * or -ENODEV if no entry is populated.
+ * Return: 0 with *@out_base / *@out_size set, or -ENODEV if @coh_idx is out
+ * of range or has no populated coh_resource[] entry.
  */
-static int pci_tsm_coherent_range(struct pci_dev *pdev, u64 *out_base,
-				  u64 *out_size)
+static int pci_tsm_coherent_range(struct pci_dev *pdev, unsigned int coh_idx,
+				  u64 *out_base, u64 *out_size)
 {
-	for (int i = 0; i < PCI_CXL_MAX_COHERENT_RANGES; i++) {
-		struct resource *res = &pdev->coh_resource[i];
+	struct resource *res;
 
-		if (!(res->flags & IORESOURCE_MEM))
-			continue;
+	if (coh_idx >= PCI_CXL_MAX_COHERENT_RANGES)
+		return -ENODEV;
 
-		*out_base = res->start;
-		*out_size = resource_size(res);
-		return 0;
-	}
+	res = &pdev->coh_resource[coh_idx];
+	if (!(res->flags & IORESOURCE_MEM))
+		return -ENODEV;
 
-	return -ENODEV;
+	*out_base = res->start;
+	*out_size = resource_size(res);
+	return 0;
 }
 #else
-static int pci_tsm_coherent_range(struct pci_dev *pdev, u64 *out_base,
-				  u64 *out_size)
+static int pci_tsm_coherent_range(struct pci_dev *pdev, unsigned int coh_idx,
+				  u64 *out_base, u64 *out_size)
 {
 	return -ENODEV;
 }
@@ -1107,6 +1116,7 @@ struct pci_tsm_mmio *pci_tsm_mmio_alloc(struct pci_dev *pdev,
 	u64 reporting_bar_base, last_reporting_end;
 	u32 mmio_range_count;
 	int last_bar = -1;
+	bool seen_coherent = false;
 	int i;
 
 	if (report_len < sizeof(*devif_report))
@@ -1135,28 +1145,32 @@ struct pci_tsm_mmio *pci_tsm_mmio_alloc(struct pci_dev *pdev,
 		u32 attr = __le32_to_cpu(mmio_data->attributes);
 		int bar = FIELD_GET(PCI_TSM_DEVIF_REPORT_MMIO_ATTR_RANGE_ID,
 				    attr);
-		bool coherent =
-			bar == PCI_TSM_DEVIF_REPORT_MMIO_RANGE_ID_COHERENT;
+		unsigned int coh_idx =
+			PCI_TSM_DEVIF_REPORT_MMIO_RANGE_ID_TO_COH_IDX(bar);
+		bool coherent = coh_idx < PCI_CXL_MAX_COHERENT_RANGES;
 
 		if (coherent) {
-			if (i != mmio_range_count - 1) {
-				pci_dbg(pdev, "Coherent reporting range is not last\n");
-				return NULL;
-			}
+			seen_coherent = true;
 
 			/*
-			 * No BAR names the coherent range, so fail closed if
-			 * neither a CXL region nor a committed HDM decoder
-			 * resolves its address.
+			 * Fail closed if pdev->coh_resource[coh_idx] isn't
+			 * populated: nothing else in the report identifies
+			 * the window's address.
 			 */
-			if (pci_tsm_coherent_range(pdev, &range_base,
+			if (pci_tsm_coherent_range(pdev, coh_idx, &range_base,
 						   &range_len)) {
-				pci_dbg(pdev, "No CXL region or committed HDM decoder for coherent reporting range\n");
+				pci_dbg(pdev, "No populated coh_resource[] entry for coherent range %u\n",
+					coh_idx);
 				return NULL;
 			}
 
-			/* Coherent range is last and not part of the BAR sequence. */
+			/* Coherent ranges are not part of the BAR sequence. */
 		} else {
+			if (seen_coherent) {
+				pci_dbg(pdev, "BAR reporting range follows a coherent range\n");
+				return NULL;
+			}
+
 			if (bar >= PCI_STD_NUM_BARS ||
 			    !(pci_resource_flags(pdev, bar) & IORESOURCE_MEM) ||
 			    (pci_resource_flags(pdev, bar) & IORESOURCE_UNSET)) {
-- 
2.43.0


      parent reply	other threads:[~2026-10-05  7:03 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-05  7:02 [RFC PATCH 0/4] PCI/TSM: Resolve TDISP coherent (CXL) ranges from precommitted HDM decoders Ankit Agrawal
2026-10-05  7:02 ` [RFC PATCH 1/4] PCI/TSM: Create MMIO descriptors via TDISP Report Ankit Agrawal
2026-10-05 11:17   ` Bradley Morgan
2026-10-05  7:02 ` [RFC PATCH 2/4] PCI/CXL: Populate and insert/remove pdev->coh_resource[] Ankit Agrawal
2026-10-05  7:02 ` [RFC PATCH 3/4] PCI/TSM: Derive the coherent-range IPA from CXL Ankit Agrawal
2026-10-05  7:02 ` Ankit Agrawal [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261005070252.84810-5-ankita@nvidia.com \
    --to=ankita@nvidia.com \
    --cc=Smita.KoralahalliChannabasappa@amd.com \
    --cc=aik@amd.com \
    --cc=alison.schofield@intel.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=aneesh.kumar@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=dave.jiang@intel.com \
    --cc=dave@stgolabs.net \
    --cc=icheng@nvidia.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=iweiny@kernel.org \
    --cc=jgg@nvidia.com \
    --cc=jic23@kernel.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=ming.li@zohomail.com \
    --cc=smadhavan@nvidia.com \
    --cc=vishal.l.verma@intel.com \
    --cc=yilun.xu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®