To enable address translation, the endpoint decoder's HPA range must
be translated when crossing memory domains to the next parent port's
address ranges up to the root port. The root port's HPA range is
equivalent to the system's SPA range.
Introduce a callback to translate an address of the decoder's HPA
range to the address range of the parent port. The callback can be set
for ports that need to handle address translation.
Reviewed-by: Gregory Price <gourry@gourry.net>
Signed-off-by: Robert Richter <rrichter@amd.com>
---
drivers/cxl/cxl.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index f182982f1c14..eb837867d932 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -429,6 +429,17 @@ struct cxl_rd_ops {
u64 (*spa_to_hpa)(struct cxl_root_decoder *cxlrd, u64 spa);
};
+/**
+ * cxl_to_hpa_fn - type of a callback function to translate an HPA
+ * @cxld: cxl_decoder to translate from
+ * @hpa: HPA of the @cxld decoder's address range
+ *
+ * The callback translates a decoder's HPA to the address range of the
+ * decoder's parent port. The return value is the translated HPA on
+ * success or ULLONG_MAX otherwise.
+ */
+typedef u64 (*cxl_to_hpa_fn)(struct cxl_decoder *cxld, u64 hpa);
+
/**
* struct cxl_root_decoder - Static platform CXL address decoder
* @res: host / parent resource for region allocations
@@ -599,6 +610,7 @@ struct cxl_dax_region {
* @parent_dport: dport that points to this port in the parent
* @decoder_ida: allocator for decoder ids
* @reg_map: component and ras register mapping parameters
+ * @to_hpa: Callback to translate a child port's decoder address to the port's HPA address range
* @nr_dports: number of entries in @dports
* @hdm_end: track last allocated HDM decoder instance for allocation ordering
* @commit_end: cursor to track highest committed decoder for commit ordering
@@ -619,6 +631,7 @@ struct cxl_port {
struct cxl_dport *parent_dport;
struct ida decoder_ida;
struct cxl_register_map reg_map;
+ cxl_to_hpa_fn to_hpa;
int nr_dports;
int hdm_end;
int commit_end;
--
2.39.5
On 9/12/25 7:45 AM, Robert Richter wrote: > To enable address translation, the endpoint decoder's HPA range must > be translated when crossing memory domains to the next parent port's > address ranges up to the root port. The root port's HPA range is > equivalent to the system's SPA range. > > Introduce a callback to translate an address of the decoder's HPA > range to the address range of the parent port. The callback can be set > for ports that need to handle address translation. > > Reviewed-by: Gregory Price <gourry@gourry.net> > Signed-off-by: Robert Richter <rrichter@amd.com> > --- > drivers/cxl/cxl.h | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h > index f182982f1c14..eb837867d932 100644 > --- a/drivers/cxl/cxl.h > +++ b/drivers/cxl/cxl.h > @@ -429,6 +429,17 @@ struct cxl_rd_ops { > u64 (*spa_to_hpa)(struct cxl_root_decoder *cxlrd, u64 spa); > }; > > +/** > + * cxl_to_hpa_fn - type of a callback function to translate an HPA > + * @cxld: cxl_decoder to translate from > + * @hpa: HPA of the @cxld decoder's address range > + * > + * The callback translates a decoder's HPA to the address range of the > + * decoder's parent port. The return value is the translated HPA on > + * success or ULLONG_MAX otherwise. > + */ > +typedef u64 (*cxl_to_hpa_fn)(struct cxl_decoder *cxld, u64 hpa); > + > /** > * struct cxl_root_decoder - Static platform CXL address decoder > * @res: host / parent resource for region allocations > @@ -599,6 +610,7 @@ struct cxl_dax_region { > * @parent_dport: dport that points to this port in the parent > * @decoder_ida: allocator for decoder ids > * @reg_map: component and ras register mapping parameters > + * @to_hpa: Callback to translate a child port's decoder address to the port's HPA address range > * @nr_dports: number of entries in @dports > * @hdm_end: track last allocated HDM decoder instance for allocation ordering > * @commit_end: cursor to track highest committed decoder for commit ordering > @@ -619,6 +631,7 @@ struct cxl_port { > struct cxl_dport *parent_dport; > struct ida decoder_ida; > struct cxl_register_map reg_map; > + cxl_to_hpa_fn to_hpa; The more I look at this, the more I feel the callback should be part of 'struct cxl_rd_ops' and not under each port. While this provides flexibility in a general case if there is a need to translate at each level, the actual use case in the field today only requires translation at the top as far as I can tell. And the translate functionality should be part of a decoder and not a port. And in this case, the root decoder would suffice. DJ > int nr_dports; > int hdm_end; > int commit_end;
On 15.09.25 13:22:14, Dave Jiang wrote: > On 9/12/25 7:45 AM, Robert Richter wrote: > > @@ -619,6 +631,7 @@ struct cxl_port { > > struct cxl_dport *parent_dport; > > struct ida decoder_ida; > > struct cxl_register_map reg_map; > > + cxl_to_hpa_fn to_hpa; > > The more I look at this, the more I feel the callback should be part > of 'struct cxl_rd_ops' and not under each port. While this provides > flexibility in a general case if there is a need to translate at > each level, the actual use case in the field today only requires > translation at the top as far as I can tell. And the translate > functionality should be part of a decoder and not a port. And in > this case, the root decoder would suffice. Ok, I see the tendence to handle this in a more specific use case. A change of the implementation should be possible, will change that. Thanks, -Robert
On 9/12/25 7:45 AM, Robert Richter wrote: > To enable address translation, the endpoint decoder's HPA range must > be translated when crossing memory domains to the next parent port's > address ranges up to the root port. The root port's HPA range is > equivalent to the system's SPA range. > > Introduce a callback to translate an address of the decoder's HPA > range to the address range of the parent port. The callback can be set > for ports that need to handle address translation. > > Reviewed-by: Gregory Price <gourry@gourry.net> > Signed-off-by: Robert Richter <rrichter@amd.com> > --- > drivers/cxl/cxl.h | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h > index f182982f1c14..eb837867d932 100644 > --- a/drivers/cxl/cxl.h > +++ b/drivers/cxl/cxl.h > @@ -429,6 +429,17 @@ struct cxl_rd_ops { > u64 (*spa_to_hpa)(struct cxl_root_decoder *cxlrd, u64 spa); > }; > > +/** > + * cxl_to_hpa_fn - type of a callback function to translate an HPA > + * @cxld: cxl_decoder to translate from > + * @hpa: HPA of the @cxld decoder's address range > + * > + * The callback translates a decoder's HPA to the address range of the > + * decoder's parent port. The return value is the translated HPA on > + * success or ULLONG_MAX otherwise. > + */ > +typedef u64 (*cxl_to_hpa_fn)(struct cxl_decoder *cxld, u64 hpa); cxl_to_parent_hpa_fn()? DJ > + > /** > * struct cxl_root_decoder - Static platform CXL address decoder > * @res: host / parent resource for region allocations > @@ -599,6 +610,7 @@ struct cxl_dax_region { > * @parent_dport: dport that points to this port in the parent > * @decoder_ida: allocator for decoder ids > * @reg_map: component and ras register mapping parameters > + * @to_hpa: Callback to translate a child port's decoder address to the port's HPA address range > * @nr_dports: number of entries in @dports > * @hdm_end: track last allocated HDM decoder instance for allocation ordering > * @commit_end: cursor to track highest committed decoder for commit ordering > @@ -619,6 +631,7 @@ struct cxl_port { > struct cxl_dport *parent_dport; > struct ida decoder_ida; > struct cxl_register_map reg_map; > + cxl_to_hpa_fn to_hpa; > int nr_dports; > int hdm_end; > int commit_end;
On 12.09.25 14:21:16, Dave Jiang wrote: > > > On 9/12/25 7:45 AM, Robert Richter wrote: > > To enable address translation, the endpoint decoder's HPA range must > > be translated when crossing memory domains to the next parent port's > > address ranges up to the root port. The root port's HPA range is > > equivalent to the system's SPA range. > > > > Introduce a callback to translate an address of the decoder's HPA > > range to the address range of the parent port. The callback can be set > > for ports that need to handle address translation. > > > > Reviewed-by: Gregory Price <gourry@gourry.net> > > Signed-off-by: Robert Richter <rrichter@amd.com> > > --- > > drivers/cxl/cxl.h | 13 +++++++++++++ > > 1 file changed, 13 insertions(+) > > > > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h > > index f182982f1c14..eb837867d932 100644 > > --- a/drivers/cxl/cxl.h > > +++ b/drivers/cxl/cxl.h > > @@ -429,6 +429,17 @@ struct cxl_rd_ops { > > u64 (*spa_to_hpa)(struct cxl_root_decoder *cxlrd, u64 spa); > > }; > > > > +/** > > + * cxl_to_hpa_fn - type of a callback function to translate an HPA > > + * @cxld: cxl_decoder to translate from > > + * @hpa: HPA of the @cxld decoder's address range > > + * > > + * The callback translates a decoder's HPA to the address range of the > > + * decoder's parent port. The return value is the translated HPA on > > + * success or ULLONG_MAX otherwise. > > + */ > > +typedef u64 (*cxl_to_hpa_fn)(struct cxl_decoder *cxld, u64 hpa); > > cxl_to_parent_hpa_fn()? It is actually a translation from the decoder's address space to the address space of the port this callback is attached to. Parent port might be confusing here and maybe the comment needs a rework too. Though, finally it is used in the context where the decoder's port is child to the port with this callback. Comment should be more precise, ok? -Robert > > DJ
On 9/15/25 12:55 AM, Robert Richter wrote: > On 12.09.25 14:21:16, Dave Jiang wrote: >> >> >> On 9/12/25 7:45 AM, Robert Richter wrote: >>> To enable address translation, the endpoint decoder's HPA range must >>> be translated when crossing memory domains to the next parent port's >>> address ranges up to the root port. The root port's HPA range is >>> equivalent to the system's SPA range. >>> >>> Introduce a callback to translate an address of the decoder's HPA >>> range to the address range of the parent port. The callback can be set >>> for ports that need to handle address translation. >>> >>> Reviewed-by: Gregory Price <gourry@gourry.net> >>> Signed-off-by: Robert Richter <rrichter@amd.com> >>> --- >>> drivers/cxl/cxl.h | 13 +++++++++++++ >>> 1 file changed, 13 insertions(+) >>> >>> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h >>> index f182982f1c14..eb837867d932 100644 >>> --- a/drivers/cxl/cxl.h >>> +++ b/drivers/cxl/cxl.h >>> @@ -429,6 +429,17 @@ struct cxl_rd_ops { >>> u64 (*spa_to_hpa)(struct cxl_root_decoder *cxlrd, u64 spa); >>> }; >>> >>> +/** >>> + * cxl_to_hpa_fn - type of a callback function to translate an HPA >>> + * @cxld: cxl_decoder to translate from >>> + * @hpa: HPA of the @cxld decoder's address range >>> + * >>> + * The callback translates a decoder's HPA to the address range of the >>> + * decoder's parent port. The return value is the translated HPA on >>> + * success or ULLONG_MAX otherwise. >>> + */ >>> +typedef u64 (*cxl_to_hpa_fn)(struct cxl_decoder *cxld, u64 hpa); >> >> cxl_to_parent_hpa_fn()? > > It is actually a translation from the decoder's address space to the > address space of the port this callback is attached to. Parent port > might be confusing here and maybe the comment needs a rework too. > Though, finally it is used in the context where the decoder's port is > child to the port with this callback. > > Comment should be more precise, ok? All I can say is naming is hard. But cxl_to_hpa_fn() doesn't exactly convey what it does, and we need something that provides a clearer intent preferably. Maybe someone else can have a better suggestion. DJ > > -Robert > >> >> DJ
© 2016 - 2025 Red Hat, Inc.