From: Robert Richter <rrichter@amd.com>
To: Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <ira.weiny@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Jonathan Cameron <Jonathan.Cameron@huawei.com>,
Dave Jiang <dave.jiang@intel.com>,
Davidlohr Bueso <dave@stgolabs.net>
Cc: <linux-cxl@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
Gregory Price <gourry@gourry.net>,
"Fabio M. De Francesco" <fabio.m.de.francesco@linux.intel.com>,
Terry Bowman <terry.bowman@amd.com>,
Robert Richter <rrichter@amd.com>
Subject: [PATCH v2 05/15] cxl/region: Calculate and store the SPA range of an endpoint
Date: Tue, 18 Feb 2025 14:23:46 +0100 [thread overview]
Message-ID: <20250218132356.1809075-6-rrichter@amd.com> (raw)
In-Reply-To: <20250218132356.1809075-1-rrichter@amd.com>
To find the correct region and root port of an endpoint of a system
needing address translation, the endpoint's HPA range must be
translated to each of the parent port address ranges up to the root
decoder.
Calculate the SPA range using the newly introduced callback function
port->to_hpa() that translates the decoder's HPA range to its parent
port's HPA range of the next outer memory domain. Introduce the helper
function cxl_port_calc_hpa() for this to calculate address ranges
using the low-level port->to_hpa() callbacks. Determine the root port
SPA range by iterating all the ports up to the root. Store the
endpoint's SPA range for later use.
Signed-off-by: Robert Richter <rrichter@amd.com>
---
drivers/cxl/core/region.c | 81 ++++++++++++++++++++++++++++++++-------
drivers/cxl/cxl.h | 1 +
2 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 6f106bfa115f..d898c9f51113 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -832,6 +832,44 @@ static int match_free_decoder(struct device *dev, const void *data)
return 1;
}
+static int cxl_port_calc_hpa(struct cxl_port *port, struct cxl_decoder *cxld,
+ struct range *hpa_range)
+{
+ struct range hpa = *hpa_range;
+ u64 len = range_len(&hpa);
+
+ if (!port->to_hpa)
+ return 0;
+
+ /* Translate HPA to the next upper domain. */
+ hpa.start = port->to_hpa(cxld, hpa.start);
+ hpa.end = port->to_hpa(cxld, hpa.end);
+
+ if (hpa.start == ULLONG_MAX || hpa.end == ULLONG_MAX) {
+ dev_warn(&port->dev,
+ "CXL address translation: HPA range invalid: %#llx-%#llx:%#llx-%#llx(%s)\n",
+ hpa.start, hpa.end, hpa_range->start,
+ hpa_range->end, dev_name(&cxld->dev));
+ return -ENXIO;
+ }
+
+ if (range_len(&hpa) != len * cxld->interleave_ways) {
+ dev_warn(&port->dev,
+ "CXL address translation: HPA range not contiguous: %#llx-%#llx:%#llx-%#llx(%s)\n",
+ hpa.start, hpa.end, hpa_range->start,
+ hpa_range->end, dev_name(&cxld->dev));
+ return -ENXIO;
+ }
+
+ if (hpa.start == hpa_range->start && hpa.end == hpa_range->end)
+ return 0;
+
+ *hpa_range = hpa;
+
+ /* Return 1 if modified. */
+ return 1;
+}
+
static int match_auto_decoder(struct device *dev, const void *data)
{
const struct cxl_region_params *p = data;
@@ -1882,6 +1920,11 @@ static int cxl_calc_interleave_pos(struct cxl_endpoint_decoder *cxled)
.hpa_range = &cxled->cxld.hpa_range,
};
+ /*
+ * Address translation is only supported for auto-discovery of
+ * decoders. There is no need to support address translation
+ * here. That is, do not recalculate ctx.hpa_range here.
+ */
for (iter = cxled_to_port(cxled); pos >= 0 && iter;
iter = parent_port_of(iter))
pos = cxl_port_calc_interleave(iter, &ctx);
@@ -3262,7 +3305,8 @@ static int cxl_endpoint_decoder_initialize(struct cxl_endpoint_decoder *cxled)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
struct cxl_port *iter = cxled_to_port(cxled);
- struct cxl_decoder *root, *cxld = &cxled->cxld;
+ struct cxl_port *parent = parent_port_of(iter);
+ struct cxl_decoder *cxld = &cxled->cxld;
struct range hpa = cxld->hpa_range;
struct cxl_interleave_context ctx;
int rc;
@@ -3271,25 +3315,33 @@ static int cxl_endpoint_decoder_initialize(struct cxl_endpoint_decoder *cxled)
.hpa_range = &hpa,
};
- while (iter && !is_cxl_root(iter)) {
+ if (!iter || !parent)
+ return -ENXIO;
+
+ while (iter && parent) {
+ /* Translate HPA to the next upper memory domain. */
+ rc = cxl_port_calc_hpa(parent, cxld, &hpa);
+ if (rc < 0)
+ return rc;
+
/* Convert interleave settings to next port upstream. */
rc = cxl_port_calc_interleave(iter, &ctx);
if (rc < 0)
return rc;
- iter = parent_port_of(iter);
- }
+ iter = parent;
+ parent = parent_port_of(iter);
- if (!iter)
- return -ENXIO;
+ if (!parent || parent->to_hpa)
+ cxld = cxl_port_find_switch_decoder(iter, &hpa);
- root = cxl_port_find_switch_decoder(iter, hpa);
- if (!root) {
- dev_err(cxlmd->dev.parent,
- "%s:%s no CXL window for range %#llx:%#llx\n",
- dev_name(&cxlmd->dev), dev_name(&cxld->dev),
- cxld->hpa_range.start, cxld->hpa_range.end);
- return -ENXIO;
+ if (!cxld) {
+ dev_err(cxlmd->dev.parent,
+ "%s:%s no CXL window for range %#llx:%#llx\n",
+ dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
+ hpa.start, hpa.end);
+ return -ENXIO;
+ }
}
dev_dbg(cxld->dev.parent,
@@ -3297,7 +3349,8 @@ static int cxl_endpoint_decoder_initialize(struct cxl_endpoint_decoder *cxled)
dev_name(&cxled->cxld.dev), dev_name(&cxld->dev),
hpa.start, hpa.end, ctx.pos);
- cxled->cxlrd = to_cxl_root_decoder(&root->dev);
+ cxled->cxlrd = to_cxl_root_decoder(&cxld->dev);
+ cxled->spa_range = hpa;
cxled->pos = ctx.pos;
return 0;
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 17496784f021..7303aec1c31c 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -394,6 +394,7 @@ struct cxl_endpoint_decoder {
struct cxl_decoder cxld;
struct cxl_root_decoder *cxlrd;
struct resource *dpa_res;
+ struct range spa_range;
resource_size_t skip;
enum cxl_decoder_state state;
int part;
--
2.39.5
next prev parent reply other threads:[~2025-02-18 13:24 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-18 13:23 [PATCH v2 00/15] cxl: Address translation support, part 2: Generic support and AMD Zen5 platform enablement Robert Richter
2025-02-18 13:23 ` [PATCH v2 01/15] cxl: Modify address translation callback for generic use Robert Richter
2025-02-20 16:00 ` Gregory Price
2025-02-20 21:03 ` Dave Jiang
2025-02-18 13:23 ` [PATCH v2 02/15] cxl: Introduce callback to translate an HPA range from a port to its parent Robert Richter
2025-02-20 21:19 ` Dave Jiang
2025-02-18 13:23 ` [PATCH v2 03/15] cxl/region: Factor out code for interleaving calculations Robert Richter
2025-02-20 16:28 ` Gregory Price
2025-02-20 16:41 ` Gregory Price
2025-03-14 12:45 ` Jonathan Cameron
2025-02-18 13:23 ` [PATCH v2 04/15] cxl/region: Calculate endpoint's region position during init Robert Richter
2025-02-19 23:32 ` Gregory Price
2025-02-20 17:31 ` Gregory Price
2025-02-20 21:56 ` Dave Jiang
2025-04-04 4:38 ` Gregory Price
2025-04-04 15:36 ` [PATCH] cxl/region: Continue recalculating position during sort Gregory Price
2025-04-04 17:22 ` Gregory Price
2025-04-05 2:35 ` [PATCH] cxl region: recalculate interleave pos during region probe Gregory Price
2025-04-08 15:30 ` Gregory Price
2025-02-18 13:23 ` Robert Richter [this message]
2025-02-20 18:42 ` [PATCH v2 05/15] cxl/region: Calculate and store the SPA range of an endpoint Gregory Price
2025-02-20 22:31 ` Dave Jiang
2025-02-20 22:37 ` Gregory Price
2025-03-14 12:41 ` Jonathan Cameron
2025-02-18 13:23 ` [PATCH v2 06/15] cxl/region: Use endpoint's HPA range to find the port's decoder Robert Richter
2025-04-24 0:28 ` Gregory Price
2025-04-24 21:49 ` Gregory Price
2025-04-24 23:46 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 07/15] cxl/region: Use translated HPA ranges " Robert Richter
2025-02-20 19:13 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 08/15] cxl/region: Use the endpoint's SPA range to find a region Robert Richter
2025-02-20 19:28 ` Gregory Price
2025-03-14 12:45 ` Jonathan Cameron
2025-04-08 15:45 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 09/15] cxl/region: Use the endpoint's SPA range to create " Robert Richter
2025-02-20 19:31 ` Gregory Price
2025-03-14 12:46 ` Jonathan Cameron
2025-04-08 15:50 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 10/15] cxl/region: Use root decoders interleaving parameters " Robert Richter
2025-02-20 19:43 ` Gregory Price
2025-03-14 12:49 ` Jonathan Cameron
2025-04-01 1:59 ` Gregory Price
2025-04-01 5:26 ` Gregory Price
2025-04-01 18:03 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 11/15] cxl/region: Use the endpoint's SPA range to check " Robert Richter
2025-02-20 19:50 ` Gregory Price
2025-04-08 15:54 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 12/15] cxl/region: Lock decoders that need address translation Robert Richter
2025-02-20 19:57 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 13/15] cxl/x86: Prepare for architectural platform setup Robert Richter
2025-02-20 19:57 ` Gregory Price
2025-02-18 13:23 ` [PATCH v2 14/15] cxl/amd: Enable Zen5 address translation using ACPI PRMT Robert Richter
2025-02-21 0:40 ` Dave Jiang
2025-03-14 13:01 ` Jonathan Cameron
2025-04-05 2:38 ` [PATCH] [HACK] drop zen5_init checks due to segfault Gregory Price
2025-05-13 21:10 ` Robert Richter
2025-06-17 20:33 ` Joshua Hahn
2025-06-24 5:43 ` Robert Richter
2025-06-24 21:46 ` Joshua Hahn
2025-02-18 13:23 ` [PATCH v2 15/15] MAINTAINERS: CXL: Add entry for AMD platform support (CXL_AMD) Robert Richter
2025-02-20 1:00 ` [PATCH v2 00/15] cxl: Address translation support, part 2: Generic support and AMD Zen5 platform enablement Gregory Price
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=20250218132356.1809075-6-rrichter@amd.com \
--to=rrichter@amd.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=fabio.m.de.francesco@linux.intel.com \
--cc=gourry@gourry.net \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=terry.bowman@amd.com \
--cc=vishal.l.verma@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