Re: [PATCH v4 3/4] cxl/hdm: Make switch decoder target parsing endian-safe
Dave Jiang <[email protected]>
| Newsgroups | org.kernel.vger.linux-cxl |
|---|---|
| Message-ID | <[email protected]> |
On 7/20/26 6:59 PM, Alison Schofield wrote:
> Switch decoder target IDs are stored one per byte, starting with
> target 0 in the least significant byte. The current code accesses
> those bytes in memory order, which only matches register order on
> little-endian hosts.
>
> On big-endian hosts, the target IDs are reversed and the decoder is
> associated with the wrong downstream ports.
>
> Extract each target ID from the register value with an explicit shift
> and mask so the target mapping is independent of host endianness.
>
> Fixes: d17d0540a0db ("cxl/core/hdm: Add CXL standard decoder enumeration to the core")
> Reviewed-by: Richard Cheng <[email protected]>
> Reviewed-by: Li Ming <[email protected]>
> Signed-off-by: Alison Schofield <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
> ---
> drivers/cxl/core/hdm.c | 9 +++------
> 1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index 1f995191baf5..077aface1a2a 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -976,14 +976,11 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
> {
> struct cxl_endpoint_decoder *cxled = NULL;
> u64 size, base, skip, dpa_size, lo, hi;
> + u64 target_list;
> bool committed;
> u32 remainder;
> int i, rc;
> u32 ctrl;
> - union {
> - u64 value;
> - unsigned char target_id[8];
> - } target_list;
>
> if (should_emulate_decoders(info))
> return cxl_setup_hdm_decoder_from_dvsec(port, cxld, dpa_base,
> @@ -1122,9 +1119,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
>
> lo = readl(hdm + CXL_HDM_DECODER0_TL_LOW(which));
> hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which));
> - target_list.value = (hi << 32) + lo;
> + target_list = (hi << 32) + lo;
> for (i = 0; i < cxld->interleave_ways; i++)
> - cxld->target_map[i] = target_list.target_id[i];
> + cxld->target_map[i] = (target_list >> (i * 8)) & 0xff;
>
> return 0;
> }