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 v1 15/29] cxl/region: Use an endpoint's SPA range to find a region
Date: Tue, 7 Jan 2025 15:10:01 +0100 [thread overview]
Message-ID: <20250107141015.3367194-16-rrichter@amd.com> (raw)
In-Reply-To: <20250107141015.3367194-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 and use it to find the endpoint's region.
Signed-off-by: Robert Richter <rrichter@amd.com>
---
drivers/cxl/core/region.c | 85 ++++++++++++++++++++++++++++++++-------
drivers/cxl/cxl.h | 1 +
2 files changed, 71 insertions(+), 15 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 09a68e266a79..007a2016760d 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -824,6 +824,41 @@ static int match_free_decoder(struct device *dev, 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 || !hpa.end ||
+ 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;
+ }
+
+ *hpa_range = hpa;
+
+ return 0;
+}
+
static int match_auto_decoder(struct device *dev, void *data)
{
struct cxl_region_params *p = data;
@@ -3214,26 +3249,47 @@ cxl_port_find_switch_decoder(struct cxl_port *port, struct range *hpa)
static int cxl_endpoint_initialize(struct cxl_endpoint_decoder *cxled)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
- struct cxl_port *iter = cxled_to_port(cxled);
- struct range *hpa = &cxled->cxld.hpa_range;
+ struct cxl_port *parent, *iter = cxled_to_port(cxled);
+ struct range hpa = cxled->cxld.hpa_range;
struct cxl_decoder *cxld = &cxled->cxld;
- while (iter && !is_cxl_root(iter))
- iter = to_cxl_port(iter->dev.parent);
-
- if (!iter)
+ if (!iter || is_cxl_root(iter))
return -ENXIO;
- cxld = cxl_port_find_switch_decoder(iter, hpa);
- if (!cxld) {
- 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;
+ while (1) {
+ parent = parent_port_of(iter);
+
+ if (is_cxl_endpoint(iter))
+ cxld = &cxled->cxld;
+ else if (!parent || parent->to_hpa)
+ cxld = cxl_port_find_switch_decoder(iter, &hpa);
+
+ 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;
+ }
+
+ /* No parent means the root port was found. */
+ if (!parent)
+ break;
+
+ /* Translate HPA to the next upper memory domain. */
+ if (cxl_port_calc_hpa(parent, cxld, &hpa))
+ return -ENXIO;
+
+ iter = parent;
}
+ dev_dbg(cxld->dev.parent,
+ "%s:%s: range:%#llx-%#llx\n",
+ dev_name(&cxled->cxld.dev), dev_name(&cxld->dev),
+ hpa.start, hpa.end);
+
cxled->cxlrd = to_cxl_root_decoder(&cxld->dev);
+ cxled->spa_range = hpa;
return 0;
}
@@ -3358,7 +3414,6 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
static int cxl_endpoint_add(struct cxl_endpoint_decoder *cxled)
{
- struct range *hpa = &cxled->cxld.hpa_range;
struct cxl_root_decoder *cxlrd = cxled->cxlrd;
struct cxl_region_params *p;
struct cxl_region *cxlr;
@@ -3370,7 +3425,7 @@ static int cxl_endpoint_add(struct cxl_endpoint_decoder *cxled)
* one does the construction and the others add to that.
*/
mutex_lock(&cxlrd->range_lock);
- cxlr = cxl_find_region_by_range(cxlrd, hpa);
+ cxlr = cxl_find_region_by_range(cxlrd, &cxled->spa_range);
if (!cxlr)
cxlr = construct_region(cxlrd, cxled);
mutex_unlock(&cxlrd->range_lock);
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index c04f66fe2a93..4ccb2b3b31c9 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -419,6 +419,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_mode mode;
enum cxl_decoder_state state;
--
2.39.5
next prev parent reply other threads:[~2025-01-07 14:11 UTC|newest]
Thread overview: 117+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-07 14:09 [PATCH v1 00/29] cxl: Add address translation support and enable AMD Zen5 platforms Robert Richter
2025-01-07 14:09 ` [PATCH v1 01/29] cxl: Remove else after return Robert Richter
2025-01-07 16:10 ` Gregory Price
2025-01-07 16:37 ` Dave Jiang
2025-01-09 12:00 ` Robert Richter
2025-01-07 14:09 ` [PATCH v1 02/29] cxl/pci: Moving code in cxl_hdm_decode_init() Robert Richter
2025-01-07 16:18 ` Gregory Price
2025-01-29 12:47 ` Robert Richter
2025-01-07 14:09 ` [PATCH v1 03/29] cxl/pci: cxl_hdm_decode_init: Move comment Robert Richter
2025-01-07 16:46 ` Gregory Price
2025-01-07 14:09 ` [PATCH v1 04/29] cxl/pci: Add comments to cxl_hdm_decode_init() Robert Richter
2025-01-07 16:51 ` Gregory Price
2025-01-13 16:47 ` Jonathan Cameron
2025-01-07 14:09 ` [PATCH v1 05/29] cxl/region: Move find_cxl_root() to cxl_add_to_region() Robert Richter
2025-01-07 16:49 ` Gregory Price
2025-01-13 16:52 ` Jonathan Cameron
2025-01-07 14:09 ` [PATCH v1 06/29] cxl/region: Factor out code to find the root decoder Robert Richter
2025-01-07 16:57 ` Gregory Price
2025-01-13 16:59 ` Jonathan Cameron
2025-01-29 13:13 ` Robert Richter
2025-01-07 14:09 ` [PATCH v1 07/29] cxl/region: Factor out code to find a root decoder's region Robert Richter
2025-01-07 16:59 ` Gregory Price
2025-01-30 16:43 ` Robert Richter
2025-01-07 14:09 ` [PATCH v1 08/29] cxl/region: Split region registration into an initialization and adding part Robert Richter
2025-01-07 18:29 ` Gregory Price
2025-01-30 16:53 ` Robert Richter
2025-01-09 1:08 ` Li Ming
2025-01-09 10:30 ` Robert Richter
2025-01-07 14:09 ` [PATCH v1 09/29] cxl/region: Use iterator to find the root port in cxl_find_root_decoder() Robert Richter
2025-01-07 17:23 ` Gregory Price
2025-01-13 18:11 ` Jonathan Cameron
2025-01-07 14:09 ` [PATCH v1 10/29] cxl/region: Add function to find a port's switch decoder by range Robert Richter
2025-01-07 18:38 ` Gregory Price
2025-01-30 16:58 ` Robert Richter
2025-01-17 21:31 ` Ben Cheatham
2025-01-30 17:02 ` Robert Richter
2025-01-07 14:09 ` [PATCH v1 11/29] cxl/region: Unfold cxl_find_root_decoder() into cxl_endpoint_initialize() Robert Richter
2025-01-07 18:41 ` Gregory Price
2025-01-07 14:09 ` [PATCH v1 12/29] cxl: Modify address translation callback for generic use Robert Richter
2025-01-07 18:44 ` Gregory Price
2025-01-31 14:19 ` Robert Richter
2025-01-17 21:31 ` Ben Cheatham
2025-01-31 14:27 ` Robert Richter
2025-01-07 14:09 ` [PATCH v1 13/29] cxl: Introduce callback to translate an HPA range from a port to its parent Robert Richter
2025-01-07 18:47 ` Gregory Price
2025-01-07 14:10 ` [PATCH v1 14/29] cxl: Introduce parent_port_of() helper Robert Richter
2025-01-07 18:50 ` Gregory Price
2025-01-13 18:20 ` Jonathan Cameron
2025-01-07 14:10 ` Robert Richter [this message]
2025-01-07 19:14 ` [PATCH v1 15/29] cxl/region: Use an endpoint's SPA range to find a region Gregory Price
2025-02-05 8:48 ` Robert Richter
2025-01-14 10:59 ` Jonathan Cameron
2025-01-31 15:46 ` Robert Richter
2025-01-17 21:31 ` Ben Cheatham
2025-02-05 9:00 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 16/29] cxl/region: Use translated HPA ranges to calculate the endpoint position Robert Richter
2025-01-07 22:01 ` Gregory Price
2025-02-05 10:38 ` Robert Richter
2025-01-17 21:31 ` Ben Cheatham
2025-02-05 10:43 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 17/29] cxl/region: Rename function to cxl_find_decoder_early() Robert Richter
2025-01-07 22:06 ` Gregory Price
2025-02-05 10:56 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 18/29] cxl/region: Avoid duplicate call of cxl_find_decoder_early() Robert Richter
2025-01-07 22:11 ` Gregory Price
2025-01-07 14:10 ` [PATCH v1 19/29] cxl/region: Use endpoint's HPA range to find the port's decoder Robert Richter
2025-01-07 22:18 ` Gregory Price
2025-02-06 10:50 ` Robert Richter
2025-01-17 21:31 ` Ben Cheatham
2025-02-06 11:03 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 20/29] cxl/region: Use translated HPA ranges " Robert Richter
2025-01-07 22:33 ` Gregory Price
2025-02-06 11:31 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 21/29] cxl/region: Lock decoders that need address translation Robert Richter
2025-01-07 22:35 ` Gregory Price
2025-02-06 13:23 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 22/29] cxl/region: Use translated HPA ranges to create a region Robert Richter
2025-01-07 23:08 ` Gregory Price
2025-02-06 13:25 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 23/29] cxl/region: Use root decoders interleaving parameters " Robert Richter
2025-01-13 17:48 ` Alison Schofield
2025-02-14 13:06 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 24/29] cxl/region: Use endpoint's SPA range to check " Robert Richter
2025-01-13 17:38 ` Alison Schofield
2025-02-14 13:09 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 25/29] cxl/amd: Enable Zen5 address translation using ACPI PRMT Robert Richter
2025-01-07 16:32 ` Robert Richter
2025-01-07 23:28 ` Gregory Price
2025-01-08 14:52 ` Robert Richter
2025-01-08 15:49 ` Gregory Price
2025-01-08 15:48 ` Gregory Price
2025-01-09 10:14 ` Robert Richter
2025-01-14 11:13 ` Jonathan Cameron
2025-01-17 7:59 ` Robert Richter
2025-01-17 11:46 ` Jonathan Cameron
2025-01-17 14:10 ` Robert Richter
2025-01-09 22:25 ` Gregory Price
2025-01-15 15:05 ` Robert Richter
2025-01-15 17:05 ` Gregory Price
2025-01-15 22:24 ` Gregory Price
2025-01-17 14:06 ` Robert Richter
2025-01-10 22:48 ` Gregory Price
2025-01-17 8:41 ` Robert Richter
2025-01-17 21:32 ` Ben Cheatham
2025-01-28 9:29 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 26/29] MAINTAINERS: CXL: Add entry for AMD platform support (CXL_AMD) Robert Richter
2025-01-07 14:10 ` [PATCH v1 27/29] cxl/region: Show message on registration failure Robert Richter
2025-01-07 23:11 ` Gregory Price
2025-01-07 14:10 ` [PATCH v1 28/29] cxl/region: Show message on broken target list Robert Richter
2025-01-07 23:12 ` Gregory Price
2025-01-14 11:16 ` Jonathan Cameron
2025-02-06 21:23 ` Robert Richter
2025-02-07 17:51 ` Jonathan Cameron
2025-02-12 9:08 ` Robert Richter
2025-01-07 14:10 ` [PATCH v1 29/29] cxl: Show message when a decoder was added to a port Robert Richter
2025-01-07 23:15 ` Gregory Price
2025-01-13 18:41 ` [PATCH v1 00/29] cxl: Add address translation support and enable AMD Zen5 platforms Alison Schofield
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=20250107141015.3367194-16-rrichter@amd.com \
--to=rrichter@amd.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=jonathan.cameron@huawei.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