* [PATCH v24 00/11] Type2 device basic support
@ 2026-03-23 11:31 alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 01/11] sfc: add cxl support alejandro.lucero-palau
` (10 more replies)
0 siblings, 11 replies; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
This patchset should be aplied on the for-7.1/cxl-type2-support branch.
For the sake of having the impending Type2 support for known drivers
needing it (sfc and Jump Trading) this version does only support the
case of HDM Type2 device committed by the BIOS, keeping the
decoders untouched when driver is unload, which requires a patch from v6
Smita's series:
https://lore.kernel.org/linux-cxl/20260210064501.157591-1-Smita.KoralahalliChannabasappa@amd.com/T/#mdad81d3817def8baace77ead9e2e305e775cf51d ?
or a BIOS locking those decoders.
Patches below same than those part of v23 but with only the code dealing
with the supported case.
Alejandro Lucero (11):
sfc: add cxl support
cxl/sfc: Map cxl regs
cxl/sfc: Initialize dpa without a mailbox
cxl: Prepare memdev creation for type2
sfc: create type2 cxl memdev
cxl/hdm: Add support for getting region from committed decoder
cxl: Add function for obtaining region range
cxl: Export function for unwinding cxl by accelerators
sfc: obtain decoder and region if committed by firmware
cxl: Avoid dax creation for accelerators
sfc: support pio mapping based on cxl
drivers/cxl/core/core.h | 2 +
drivers/cxl/core/hdm.c | 39 +++++++++
drivers/cxl/core/mbox.c | 51 +----------
drivers/cxl/core/memdev.c | 81 +++++++++++++++++-
drivers/cxl/core/pci.c | 1 +
drivers/cxl/core/port.c | 1 +
drivers/cxl/core/region.c | 47 ++++++++--
drivers/cxl/core/regs.c | 1 +
drivers/cxl/cxlmem.h | 6 --
drivers/cxl/cxlpci.h | 12 ---
drivers/cxl/mem.c | 45 +++++++---
drivers/cxl/pci.c | 1 +
drivers/net/ethernet/sfc/Kconfig | 9 ++
drivers/net/ethernet/sfc/Makefile | 1 +
drivers/net/ethernet/sfc/ef10.c | 53 ++++++++++--
drivers/net/ethernet/sfc/efx.c | 15 +++-
drivers/net/ethernet/sfc/efx_cxl.c | 119 ++++++++++++++++++++++++++
drivers/net/ethernet/sfc/efx_cxl.h | 40 +++++++++
drivers/net/ethernet/sfc/net_driver.h | 12 +++
drivers/net/ethernet/sfc/nic.h | 3 +
include/cxl/cxl.h | 14 +++
include/cxl/pci.h | 21 +++++
22 files changed, 480 insertions(+), 94 deletions(-)
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
create mode 100644 include/cxl/pci.h
base-commit: 64584273dfb8a1e5fc7d78094ba22a93c204b44e
--
2.34.1
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v24 01/11] sfc: add cxl support
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-24 16:29 ` Jonathan Cameron
2026-03-23 11:31 ` [PATCH v24 02/11] cxl/sfc: Map cxl regs alejandro.lucero-palau
` (9 subsequent siblings)
10 siblings, 1 reply; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Jonathan Cameron, Edward Cree, Alison Schofield
From: Alejandro Lucero <alucerop@amd.com>
Add CXL initialization based on new CXL API for accel drivers and make
it dependent on kernel CXL configuration.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/net/ethernet/sfc/Kconfig | 9 +++++
drivers/net/ethernet/sfc/Makefile | 1 +
drivers/net/ethernet/sfc/efx.c | 15 ++++++-
drivers/net/ethernet/sfc/efx_cxl.c | 56 +++++++++++++++++++++++++++
drivers/net/ethernet/sfc/efx_cxl.h | 40 +++++++++++++++++++
drivers/net/ethernet/sfc/net_driver.h | 10 +++++
6 files changed, 130 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index c4c43434f314..979f2801e2a8 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -66,6 +66,15 @@ config SFC_MCDI_LOGGING
Driver-Interface) commands and responses, allowing debugging of
driver/firmware interaction. The tracing is actually enabled by
a sysfs file 'mcdi_logging' under the PCI device.
+config SFC_CXL
+ bool "Solarflare SFC9100-family CXL support"
+ depends on SFC && CXL_BUS >= SFC
+ default SFC
+ help
+ This enables SFC CXL support if the kernel is configuring CXL for
+ using CTPIO with CXL.mem. The SFC device with CXL support and
+ with a CXL-aware firmware can be used for minimizing latencies
+ when sending through CTPIO.
source "drivers/net/ethernet/sfc/falcon/Kconfig"
source "drivers/net/ethernet/sfc/siena/Kconfig"
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
index d99039ec468d..bb0f1891cde6 100644
--- a/drivers/net/ethernet/sfc/Makefile
+++ b/drivers/net/ethernet/sfc/Makefile
@@ -13,6 +13,7 @@ sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
mae.o tc.o tc_bindings.o tc_counters.o \
tc_encap_actions.o tc_conntrack.o
+sfc-$(CONFIG_SFC_CXL) += efx_cxl.o
obj-$(CONFIG_SFC) += sfc.o
obj-$(CONFIG_SFC_FALCON) += falcon/
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 8f136a11d396..c1e6e31f07cf 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -34,6 +34,7 @@
#include "selftest.h"
#include "sriov.h"
#include "efx_devlink.h"
+#include "efx_cxl.h"
#include "mcdi_port_common.h"
#include "mcdi_pcol.h"
@@ -981,12 +982,15 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_pci_remove_main(efx);
efx_fini_io(efx);
+
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+ efx_cxl_exit(probe_data);
+
pci_dbg(efx->pci_dev, "shutdown successful\n");
efx_fini_devlink_and_unlock(efx);
efx_fini_struct(efx);
free_netdev(efx->net_dev);
- probe_data = container_of(efx, struct efx_probe_data, efx);
kfree(probe_data);
};
@@ -1190,6 +1194,15 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
if (rc)
goto fail2;
+ /* A successful cxl initialization implies a CXL region created to be
+ * used for PIO buffers. If there is no CXL support, or initialization
+ * fails, efx_cxl_pio_initialised will be false and legacy PIO buffers
+ * defined at specific PCI BAR regions will be used.
+ */
+ rc = efx_cxl_init(probe_data);
+ if (rc)
+ pci_err(pci_dev, "CXL initialization failed with error %d\n", rc);
+
rc = efx_pci_probe_post_io(efx);
if (rc) {
/* On failure, retry once immediately.
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
new file mode 100644
index 000000000000..8e0481d8dced
--- /dev/null
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ *
+ * Driver for AMD network controllers and boards
+ * Copyright (C) 2025, Advanced Micro Devices, Inc.
+ */
+
+#include <linux/pci.h>
+
+#include "net_driver.h"
+#include "efx_cxl.h"
+
+#define EFX_CTPIO_BUFFER_SIZE SZ_256M
+
+int efx_cxl_init(struct efx_probe_data *probe_data)
+{
+ struct efx_nic *efx = &probe_data->efx;
+ struct pci_dev *pci_dev = efx->pci_dev;
+ struct efx_cxl *cxl;
+ u16 dvsec;
+
+ probe_data->cxl_pio_initialised = false;
+
+ /* Is the device configured with and using CXL? */
+ if (!pcie_is_cxl(pci_dev))
+ return 0;
+
+ dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
+ PCI_DVSEC_CXL_DEVICE);
+ if (!dvsec) {
+ pci_err(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability not found\n");
+ return 0;
+ }
+
+ pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
+
+ /* Create a cxl_dev_state embedded in the cxl struct using cxl core api
+ * specifying no mbox available.
+ */
+ cxl = devm_cxl_dev_state_create(&pci_dev->dev, CXL_DEVTYPE_DEVMEM,
+ pci_dev->dev.id, dvsec, struct efx_cxl,
+ cxlds, false);
+
+ if (!cxl)
+ return -ENOMEM;
+
+ probe_data->cxl = cxl;
+
+ return 0;
+}
+
+void efx_cxl_exit(struct efx_probe_data *probe_data)
+{
+}
+
+MODULE_IMPORT_NS("CXL");
diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
new file mode 100644
index 000000000000..961639cef692
--- /dev/null
+++ b/drivers/net/ethernet/sfc/efx_cxl.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for AMD network controllers and boards
+ * Copyright (C) 2025, Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_CXL_H
+#define EFX_CXL_H
+
+#ifdef CONFIG_SFC_CXL
+
+#include <cxl/cxl.h>
+
+struct cxl_root_decoder;
+struct cxl_port;
+struct cxl_endpoint_decoder;
+struct cxl_region;
+struct efx_probe_data;
+
+struct efx_cxl {
+ struct cxl_dev_state cxlds;
+ struct cxl_memdev *cxlmd;
+ struct cxl_root_decoder *cxlrd;
+ struct cxl_port *endpoint;
+ struct cxl_endpoint_decoder *cxled;
+ struct cxl_region *efx_region;
+ void __iomem *ctpio_cxl;
+};
+
+int efx_cxl_init(struct efx_probe_data *probe_data);
+void efx_cxl_exit(struct efx_probe_data *probe_data);
+#else
+static inline int efx_cxl_init(struct efx_probe_data *probe_data) { return 0; }
+static inline void efx_cxl_exit(struct efx_probe_data *probe_data) {}
+#endif
+#endif
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index b98c259f672d..3964b2c56609 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1197,14 +1197,24 @@ struct efx_nic {
atomic_t n_rx_noskb_drops;
};
+#ifdef CONFIG_SFC_CXL
+struct efx_cxl;
+#endif
+
/**
* struct efx_probe_data - State after hardware probe
* @pci_dev: The PCI device
* @efx: Efx NIC details
+ * @cxl: details of related cxl objects
+ * @cxl_pio_initialised: cxl initialization outcome.
*/
struct efx_probe_data {
struct pci_dev *pci_dev;
struct efx_nic efx;
+#ifdef CONFIG_SFC_CXL
+ struct efx_cxl *cxl;
+ bool cxl_pio_initialised;
+#endif
};
static inline struct efx_nic *efx_netdev_priv(struct net_device *dev)
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 02/11] cxl/sfc: Map cxl regs
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 01/11] sfc: add cxl support alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-24 16:33 ` Jonathan Cameron
2026-03-23 11:31 ` [PATCH v24 03/11] cxl/sfc: Initialize dpa without a mailbox alejandro.lucero-palau
` (8 subsequent siblings)
10 siblings, 1 reply; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Jonathan Cameron, Ben Cheatham, Edward Cree
From: Alejandro Lucero <alucerop@amd.com>
Export cxl core functions for a Type2 driver being able to discover and
map the device registers.
Use it in sfc driver cxl initialization.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
---
drivers/cxl/core/pci.c | 1 +
drivers/cxl/core/port.c | 1 +
drivers/cxl/core/regs.c | 1 +
drivers/cxl/cxlpci.h | 12 ------------
drivers/cxl/pci.c | 1 +
drivers/net/ethernet/sfc/efx_cxl.c | 27 +++++++++++++++++++++++++++
include/cxl/pci.h | 21 +++++++++++++++++++++
7 files changed, 52 insertions(+), 12 deletions(-)
create mode 100644 include/cxl/pci.h
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index d1f487b3d809..2bcd683aa286 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -6,6 +6,7 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/pci-doe.h>
+#include <cxl/pci.h>
#include <linux/aer.h>
#include <cxlpci.h>
#include <cxlmem.h>
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 0c5957d1d329..a53b87de70e5 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -11,6 +11,7 @@
#include <linux/idr.h>
#include <linux/node.h>
#include <cxl/einj.h>
+#include <cxl/pci.h>
#include <cxlmem.h>
#include <cxlpci.h>
#include <cxl.h>
diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
index 93710cf4f0a6..20c2d9fbcfe7 100644
--- a/drivers/cxl/core/regs.c
+++ b/drivers/cxl/core/regs.c
@@ -4,6 +4,7 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/pci.h>
+#include <cxl/pci.h>
#include <cxlmem.h>
#include <cxlpci.h>
#include <pmu.h>
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index b826eb53cf7b..110ec9c44f09 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -13,16 +13,6 @@
*/
#define CXL_PCI_DEFAULT_MAX_VECTORS 16
-/* Register Block Identifier (RBI) */
-enum cxl_regloc_type {
- CXL_REGLOC_RBI_EMPTY = 0,
- CXL_REGLOC_RBI_COMPONENT,
- CXL_REGLOC_RBI_VIRT,
- CXL_REGLOC_RBI_MEMDEV,
- CXL_REGLOC_RBI_PMU,
- CXL_REGLOC_RBI_TYPES
-};
-
/*
* Table Access DOE, CDAT Read Entry Response
*
@@ -112,6 +102,4 @@ static inline void devm_cxl_port_ras_setup(struct cxl_port *port)
}
#endif
-int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
- struct cxl_register_map *map);
#endif /* __CXL_PCI_H__ */
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index adc7c4bcb03a..5cad118e7101 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -11,6 +11,7 @@
#include <linux/pci.h>
#include <linux/aer.h>
#include <linux/io.h>
+#include <cxl/pci.h>
#include <cxl/mailbox.h>
#include "cxlmem.h"
#include "cxlpci.h"
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 8e0481d8dced..7917118e4eba 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -7,6 +7,8 @@
#include <linux/pci.h>
+#include <cxl/cxl.h>
+#include <cxl/pci.h>
#include "net_driver.h"
#include "efx_cxl.h"
@@ -18,6 +20,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
struct pci_dev *pci_dev = efx->pci_dev;
struct efx_cxl *cxl;
u16 dvsec;
+ int rc;
probe_data->cxl_pio_initialised = false;
@@ -44,6 +47,30 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
if (!cxl)
return -ENOMEM;
+ rc = cxl_pci_setup_regs(pci_dev, CXL_REGLOC_RBI_COMPONENT,
+ &cxl->cxlds.reg_map);
+ if (rc) {
+ pci_err(pci_dev, "No component registers\n");
+ return rc;
+ }
+
+ if (!cxl->cxlds.reg_map.component_map.hdm_decoder.valid) {
+ pci_err(pci_dev, "Expected HDM component register not found\n");
+ return -ENODEV;
+ }
+
+ if (!cxl->cxlds.reg_map.component_map.ras.valid) {
+ pci_err(pci_dev, "Expected RAS component register not found\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Set media ready explicitly as there are neither mailbox for checking
+ * this state nor the CXL register involved, both not mandatory for
+ * type2.
+ */
+ cxl->cxlds.media_ready = true;
+
probe_data->cxl = cxl;
return 0;
diff --git a/include/cxl/pci.h b/include/cxl/pci.h
new file mode 100644
index 000000000000..a172439f08c6
--- /dev/null
+++ b/include/cxl/pci.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+
+#ifndef __CXL_CXL_PCI_H__
+#define __CXL_CXL_PCI_H__
+
+/* Register Block Identifier (RBI) */
+enum cxl_regloc_type {
+ CXL_REGLOC_RBI_EMPTY = 0,
+ CXL_REGLOC_RBI_COMPONENT,
+ CXL_REGLOC_RBI_VIRT,
+ CXL_REGLOC_RBI_MEMDEV,
+ CXL_REGLOC_RBI_PMU,
+ CXL_REGLOC_RBI_TYPES
+};
+
+struct cxl_register_map;
+
+int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
+ struct cxl_register_map *map);
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 03/11] cxl/sfc: Initialize dpa without a mailbox
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 01/11] sfc: add cxl support alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 02/11] cxl/sfc: Map cxl regs alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 04/11] cxl: Prepare memdev creation for type2 alejandro.lucero-palau
` (7 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Ben Cheatham, Jonathan Cameron, Edward Cree
From: Alejandro Lucero <alucerop@amd.com>
Type3 relies on mailbox CXL_MBOX_OP_IDENTIFY command for initializing
memdev state params which end up being used for DPA initialization.
Allow a Type2 driver to initialize DPA simply by giving the size of its
volatile hardware partition.
Move related functions to memdev.
Add sfc driver as the client.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
---
drivers/cxl/core/core.h | 2 +
drivers/cxl/core/mbox.c | 51 +----------------------
drivers/cxl/core/memdev.c | 66 ++++++++++++++++++++++++++++++
drivers/net/ethernet/sfc/efx_cxl.c | 5 +++
include/cxl/cxl.h | 2 +
5 files changed, 76 insertions(+), 50 deletions(-)
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 5539e941782f..77c684744771 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -97,6 +97,8 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
struct dentry *cxl_debugfs_create_dir(const char *dir);
int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
enum cxl_partition_mode mode);
+struct cxl_memdev_state;
+int cxl_mem_get_partition_info(struct cxl_memdev_state *mds);
int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size);
int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled);
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 451ff2287b44..cf37676068c2 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -1151,7 +1151,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, "CXL");
*
* See CXL @8.2.9.5.2.1 Get Partition Info
*/
-static int cxl_mem_get_partition_info(struct cxl_memdev_state *mds)
+int cxl_mem_get_partition_info(struct cxl_memdev_state *mds)
{
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
struct cxl_mbox_get_partition_info pi;
@@ -1307,55 +1307,6 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd)
return -EBUSY;
}
-static void add_part(struct cxl_dpa_info *info, u64 start, u64 size, enum cxl_partition_mode mode)
-{
- int i = info->nr_partitions;
-
- if (size == 0)
- return;
-
- info->part[i].range = (struct range) {
- .start = start,
- .end = start + size - 1,
- };
- info->part[i].mode = mode;
- info->nr_partitions++;
-}
-
-int cxl_mem_dpa_fetch(struct cxl_memdev_state *mds, struct cxl_dpa_info *info)
-{
- struct cxl_dev_state *cxlds = &mds->cxlds;
- struct device *dev = cxlds->dev;
- int rc;
-
- if (!cxlds->media_ready) {
- info->size = 0;
- return 0;
- }
-
- info->size = mds->total_bytes;
-
- if (mds->partition_align_bytes == 0) {
- add_part(info, 0, mds->volatile_only_bytes, CXL_PARTMODE_RAM);
- add_part(info, mds->volatile_only_bytes,
- mds->persistent_only_bytes, CXL_PARTMODE_PMEM);
- return 0;
- }
-
- rc = cxl_mem_get_partition_info(mds);
- if (rc) {
- dev_err(dev, "Failed to query partition information\n");
- return rc;
- }
-
- add_part(info, 0, mds->active_volatile_bytes, CXL_PARTMODE_RAM);
- add_part(info, mds->active_volatile_bytes, mds->active_persistent_bytes,
- CXL_PARTMODE_PMEM);
-
- return 0;
-}
-EXPORT_SYMBOL_NS_GPL(cxl_mem_dpa_fetch, "CXL");
-
int cxl_get_dirty_count(struct cxl_memdev_state *mds, u32 *count)
{
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index 99e422594885..166ec6b7d041 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -582,6 +582,72 @@ bool is_cxl_memdev(const struct device *dev)
}
EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL");
+static void add_part(struct cxl_dpa_info *info, u64 start, u64 size, enum cxl_partition_mode mode)
+{
+ int i = info->nr_partitions;
+
+ if (size == 0)
+ return;
+
+ info->part[i].range = (struct range) {
+ .start = start,
+ .end = start + size - 1,
+ };
+ info->part[i].mode = mode;
+ info->nr_partitions++;
+}
+
+int cxl_mem_dpa_fetch(struct cxl_memdev_state *mds, struct cxl_dpa_info *info)
+{
+ struct cxl_dev_state *cxlds = &mds->cxlds;
+ struct device *dev = cxlds->dev;
+ int rc;
+
+ if (!cxlds->media_ready) {
+ info->size = 0;
+ return 0;
+ }
+
+ info->size = mds->total_bytes;
+
+ if (mds->partition_align_bytes == 0) {
+ add_part(info, 0, mds->volatile_only_bytes, CXL_PARTMODE_RAM);
+ add_part(info, mds->volatile_only_bytes,
+ mds->persistent_only_bytes, CXL_PARTMODE_PMEM);
+ return 0;
+ }
+
+ rc = cxl_mem_get_partition_info(mds);
+ if (rc) {
+ dev_err(dev, "Failed to query partition information\n");
+ return rc;
+ }
+
+ add_part(info, 0, mds->active_volatile_bytes, CXL_PARTMODE_RAM);
+ add_part(info, mds->active_volatile_bytes, mds->active_persistent_bytes,
+ CXL_PARTMODE_PMEM);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_mem_dpa_fetch, "CXL");
+
+/**
+ * cxl_set_capacity: initialize dpa by a driver without a mailbox.
+ *
+ * @cxlds: pointer to cxl_dev_state
+ * @capacity: device volatile memory size
+ */
+int cxl_set_capacity(struct cxl_dev_state *cxlds, u64 capacity)
+{
+ struct cxl_dpa_info range_info = {
+ .size = capacity,
+ };
+
+ add_part(&range_info, 0, capacity, CXL_PARTMODE_RAM);
+ return cxl_dpa_setup(cxlds, &range_info);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_set_capacity, "CXL");
+
/**
* set_exclusive_cxl_commands() - atomically disable user cxl commands
* @mds: The device state to operate on
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 7917118e4eba..a52238ac9eaa 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -71,6 +71,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
*/
cxl->cxlds.media_ready = true;
+ if (cxl_set_capacity(&cxl->cxlds, EFX_CTPIO_BUFFER_SIZE)) {
+ pci_err(pci_dev, "dpa capacity setup failed\n");
+ return -ENODEV;
+ }
+
probe_data->cxl = cxl;
return 0;
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index fa7269154620..1346771edc4e 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -223,4 +223,6 @@ struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev,
(drv_struct *)_devm_cxl_dev_state_create(parent, type, serial, dvsec, \
sizeof(drv_struct), mbox); \
})
+
+int cxl_set_capacity(struct cxl_dev_state *cxlds, u64 capacity);
#endif /* __CXL_CXL_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 04/11] cxl: Prepare memdev creation for type2
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (2 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 03/11] cxl/sfc: Initialize dpa without a mailbox alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 05/11] sfc: create type2 cxl memdev alejandro.lucero-palau
` (6 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Ben Cheatham, Jonathan Cameron,
Alison Schofield
From: Alejandro Lucero <alucerop@amd.com>
Current cxl core is relying on a CXL_DEVTYPE_CLASSMEM type device when
creating a memdev leading to problems when obtaining cxl_memdev_state
references from a CXL_DEVTYPE_DEVMEM type.
Modify check for obtaining cxl_memdev_state adding CXL_DEVTYPE_DEVMEM
support.
Make devm_cxl_add_memdev accessible from an accel driver.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/cxl/core/memdev.c | 15 +++++++++++--
drivers/cxl/cxlmem.h | 6 ------
drivers/cxl/mem.c | 45 +++++++++++++++++++++++++++++----------
include/cxl/cxl.h | 6 ++++++
4 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index 166ec6b7d041..759b43364ed7 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -7,6 +7,7 @@
#include <linux/slab.h>
#include <linux/idr.h>
#include <linux/pci.h>
+#include <cxl/cxl.h>
#include <cxlmem.h>
#include "trace.h"
#include "core.h"
@@ -576,9 +577,16 @@ static const struct device_type cxl_memdev_type = {
.groups = cxl_memdev_attribute_groups,
};
+static const struct device_type cxl_accel_memdev_type = {
+ .name = "cxl_accel_memdev",
+ .release = cxl_memdev_release,
+ .devnode = cxl_memdev_devnode,
+};
+
bool is_cxl_memdev(const struct device *dev)
{
- return dev->type == &cxl_memdev_type;
+ return (dev->type == &cxl_memdev_type ||
+ dev->type == &cxl_accel_memdev_type);
}
EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL");
@@ -773,7 +781,10 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
dev->parent = cxlds->dev;
dev->bus = &cxl_bus_type;
dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
- dev->type = &cxl_memdev_type;
+ if (cxlds->type == CXL_DEVTYPE_DEVMEM)
+ dev->type = &cxl_accel_memdev_type;
+ else
+ dev->type = &cxl_memdev_type;
device_set_pm_not_required(dev);
INIT_WORK(&cxlmd->detach_work, detach_memdev);
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 281546de426e..c98db6f18aa2 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -34,10 +34,6 @@
(FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \
CXLMDEV_RESET_NEEDED_NOT)
-struct cxl_memdev_attach {
- int (*probe)(struct cxl_memdev *cxlmd);
-};
-
/**
* struct cxl_memdev - CXL bus object representing a Type-3 Memory Device
* @dev: driver core device object
@@ -103,8 +99,6 @@ static inline bool is_cxl_endpoint(struct cxl_port *port)
struct cxl_memdev *__devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
const struct cxl_memdev_attach *attach);
-struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
- const struct cxl_memdev_attach *attach);
int devm_cxl_sanitize_setup_notifier(struct device *host,
struct cxl_memdev *cxlmd);
struct cxl_memdev_state;
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index fcffe24dcb42..ff858318091f 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -65,6 +65,26 @@ static int cxl_debugfs_poison_clear(void *data, u64 dpa)
DEFINE_DEBUGFS_ATTRIBUTE(cxl_poison_clear_fops, NULL,
cxl_debugfs_poison_clear, "%llx\n");
+static void cxl_memdev_poison_enable(struct cxl_memdev_state *mds,
+ struct cxl_memdev *cxlmd,
+ struct dentry *dentry)
+{
+ /*
+ * Avoid poison debugfs for DEVMEM aka accelerators as they rely on
+ * cxl_memdev_state.
+ */
+ if (!mds)
+ return;
+
+ if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
+ debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
+ &cxl_poison_inject_fops);
+
+ if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
+ debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
+ &cxl_poison_clear_fops);
+}
+
static int cxl_mem_probe(struct device *dev)
{
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
@@ -92,12 +112,7 @@ static int cxl_mem_probe(struct device *dev)
dentry = cxl_debugfs_create_dir(dev_name(dev));
debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
- if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
- debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
- &cxl_poison_inject_fops);
- if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
- debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
- &cxl_poison_clear_fops);
+ cxl_memdev_poison_enable(mds, cxlmd, dentry);
rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
if (rc)
@@ -206,16 +221,24 @@ static ssize_t trigger_poison_list_store(struct device *dev,
}
static DEVICE_ATTR_WO(trigger_poison_list);
-static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
+static bool cxl_poison_attr_visible(struct kobject *kobj, struct attribute *a)
{
struct device *dev = kobj_to_dev(kobj);
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
- if (a == &dev_attr_trigger_poison_list.attr)
- if (!test_bit(CXL_POISON_ENABLED_LIST,
- mds->poison.enabled_cmds))
- return 0;
+ if (!mds ||
+ !test_bit(CXL_POISON_ENABLED_LIST, mds->poison.enabled_cmds))
+ return false;
+
+ return true;
+}
+
+static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
+{
+ if (a == &dev_attr_trigger_poison_list.attr &&
+ !cxl_poison_attr_visible(kobj, a))
+ return 0;
return a->mode;
}
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 1346771edc4e..10a9b8fa2f6b 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -149,6 +149,10 @@ struct cxl_dpa_partition {
#define CXL_NR_PARTITIONS_MAX 2
+struct cxl_memdev_attach {
+ int (*probe)(struct cxl_memdev *cxlmd);
+};
+
/**
* struct cxl_dev_state - The driver device state
*
@@ -225,4 +229,6 @@ struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev,
})
int cxl_set_capacity(struct cxl_dev_state *cxlds, u64 capacity);
+struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
+ const struct cxl_memdev_attach *attach);
#endif /* __CXL_CXL_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 05/11] sfc: create type2 cxl memdev
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (3 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 04/11] cxl: Prepare memdev creation for type2 alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder alejandro.lucero-palau
` (5 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Martin Habets, Fan Ni, Edward Cree,
Jonathan Cameron
From: Alejandro Lucero <alucerop@amd.com>
Use cxl API for creating a cxl memory device using the type2
cxl_dev_state struct.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Martin Habets <habetsm.xilinx@gmail.com>
Reviewed-by: Fan Ni <fan.ni@samsung.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index a52238ac9eaa..22a7d1d95425 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -76,6 +76,12 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
return -ENODEV;
}
+ cxl->cxlmd = devm_cxl_add_memdev(&cxl->cxlds, NULL);
+ if (IS_ERR(cxl->cxlmd)) {
+ pci_err(pci_dev, "CXL accel memdev creation failed");
+ return PTR_ERR(cxl->cxlmd);
+ }
+
probe_data->cxl = cxl;
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (4 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 05/11] sfc: create type2 cxl memdev alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-24 16:48 ` Jonathan Cameron
2026-03-24 17:32 ` Dave Jiang
2026-03-23 11:31 ` [PATCH v24 07/11] cxl: Add function for obtaining region range alejandro.lucero-palau
` (4 subsequent siblings)
10 siblings, 2 replies; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
A Type2 device configured by the BIOS can already have its HDM
committed. Add a cxl_get_committed_decoder() function for cheking
so after memdev creation. A CXL region should have been created
during memdev initialization, therefore a Type2 driver can ask for
such a region for working with the HPA. If the HDM is not committed,
a Type2 driver will create the region after obtaining proper HPA
and DPA space.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
---
drivers/cxl/core/hdm.c | 39 +++++++++++++++++++++++++++++++++++++++
include/cxl/cxl.h | 3 +++
2 files changed, 42 insertions(+)
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index c222e98ae736..006be88efaa5 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -686,6 +686,45 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
}
+static int find_committed_endpoint_decoder(struct device *dev, const void *data)
+{
+ struct cxl_endpoint_decoder *cxled;
+ struct cxl_port *port;
+
+ if (!is_endpoint_decoder(dev))
+ return 0;
+
+ cxled = to_cxl_endpoint_decoder(dev);
+ port = cxled_to_port(cxled);
+
+ return cxled->cxld.id == port->hdm_end;
+}
+
+struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
+ struct cxl_region **cxlr)
+{
+ struct cxl_port *endpoint = cxlmd->endpoint;
+ struct cxl_endpoint_decoder *cxled;
+ struct device *cxled_dev;
+
+ if (!endpoint)
+ return NULL;
+
+ guard(rwsem_read)(&cxl_rwsem.dpa);
+ cxled_dev = device_find_child(&endpoint->dev, NULL,
+ find_committed_endpoint_decoder);
+
+ if (!cxled_dev)
+ return NULL;
+
+ cxled = to_cxl_endpoint_decoder(cxled_dev);
+ *cxlr = cxled->cxld.region;
+
+ put_device(cxled_dev);
+ return cxled;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_get_committed_decoder, "CXL");
+
static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
{
u16 eig;
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 10a9b8fa2f6b..2a61138e2a73 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -231,4 +231,7 @@ struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev,
int cxl_set_capacity(struct cxl_dev_state *cxlds, u64 capacity);
struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
const struct cxl_memdev_attach *attach);
+struct cxl_region;
+struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
+ struct cxl_region **cxlr);
#endif /* __CXL_CXL_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 07/11] cxl: Add function for obtaining region range
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (5 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators alejandro.lucero-palau
` (3 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Zhi Wang, Jonathan Cameron
From: Alejandro Lucero <alucerop@amd.com>
A CXL region struct contains the physical address to work with.
Type2 drivers can create a CXL region but have not access to the
related struct as it is defined as private by the kernel CXL core.
Add a function for getting the cxl region range to be used for mapping
such memory range by a Type2 driver.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Zhi Wang <zhiw@nvidia.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/cxl/core/region.c | 23 +++++++++++++++++++++++
include/cxl/cxl.h | 2 ++
2 files changed, 25 insertions(+)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 3edb5703d6de..9c3ba911d865 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2655,6 +2655,29 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
return ERR_PTR(rc);
}
+/**
+ * cxl_get_region_range - obtain range linked to a CXL region
+ *
+ * @region: a pointer to struct cxl_region
+ * @range: a pointer to a struct range to be set
+ *
+ * Returns 0 or error.
+ */
+int cxl_get_region_range(struct cxl_region *region, struct range *range)
+{
+ if (WARN_ON_ONCE(!region))
+ return -ENODEV;
+
+ if (!region->params.res)
+ return -ENOSPC;
+
+ range->start = region->params.res->start;
+ range->end = region->params.res->end;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_get_region_range, "CXL");
+
static ssize_t __create_region_show(struct cxl_root_decoder *cxlrd, char *buf)
{
return sysfs_emit(buf, "region%u\n", atomic_read(&cxlrd->region_id));
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 2a61138e2a73..122b3331469d 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -234,4 +234,6 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
struct cxl_region;
struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
struct cxl_region **cxlr);
+struct range;
+int cxl_get_region_range(struct cxl_region *region, struct range *range);
#endif /* __CXL_CXL_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (6 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 07/11] cxl: Add function for obtaining region range alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-24 16:50 ` Jonathan Cameron
2026-03-23 11:31 ` [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware alejandro.lucero-palau
` (2 subsequent siblings)
10 siblings, 1 reply; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero
From: Alejandro Lucero <alucerop@amd.com>
Add cxl_unregister_region() to the accelerator driver API
for a clean exit.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/cxl/core/region.c | 17 ++++++++++++-----
include/cxl/cxl.h | 1 +
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 9c3ba911d865..8bb53a095290 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2468,9 +2468,8 @@ static struct cxl_region *to_cxl_region(struct device *dev)
return container_of(dev, struct cxl_region, dev);
}
-static void unregister_region(void *_cxlr)
+void cxl_unregister_region(struct cxl_region *cxlr)
{
- struct cxl_region *cxlr = _cxlr;
struct cxl_region_params *p = &cxlr->params;
int i;
@@ -2489,6 +2488,14 @@ static void unregister_region(void *_cxlr)
cxl_region_iomem_release(cxlr);
put_device(&cxlr->dev);
}
+EXPORT_SYMBOL_NS_GPL(cxl_unregister_region, "CXL");
+
+static void __unregister_region(void *_cxlr)
+{
+ struct cxl_region *cxlr = _cxlr;
+
+ return cxl_unregister_region(cxlr);
+}
static struct lock_class_key cxl_region_key;
@@ -2642,7 +2649,7 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
if (rc)
goto err;
- rc = devm_add_action_or_reset(port->uport_dev, unregister_region, cxlr);
+ rc = devm_add_action_or_reset(port->uport_dev, __unregister_region, cxlr);
if (rc)
return ERR_PTR(rc);
@@ -2797,7 +2804,7 @@ static ssize_t delete_region_store(struct device *dev,
if (IS_ERR(cxlr))
return PTR_ERR(cxlr);
- devm_release_action(port->uport_dev, unregister_region, cxlr);
+ devm_release_action(port->uport_dev, __unregister_region, cxlr);
put_device(&cxlr->dev);
return len;
@@ -3963,7 +3970,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
rc = __construct_region(cxlr, ctx);
if (rc) {
- devm_release_action(port->uport_dev, unregister_region, cxlr);
+ devm_release_action(port->uport_dev, __unregister_region, cxlr);
return ERR_PTR(rc);
}
diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
index 122b3331469d..b8cdc604480a 100644
--- a/include/cxl/cxl.h
+++ b/include/cxl/cxl.h
@@ -236,4 +236,5 @@ struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
struct cxl_region **cxlr);
struct range;
int cxl_get_region_range(struct cxl_region *region, struct range *range);
+void cxl_unregister_region(struct cxl_region *cxlr);
#endif /* __CXL_CXL_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (7 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-24 16:56 ` Jonathan Cameron
2026-03-24 17:38 ` Dave Jiang
2026-03-23 11:31 ` [PATCH v24 10/11] cxl: Avoid dax creation for accelerators alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 11/11] sfc: support pio mapping based on cxl alejandro.lucero-palau
10 siblings, 2 replies; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Edward Cree
From: Alejandro Lucero <alucerop@amd.com>
Check if device HDM is already committed during firmware/BIOS
initialization.
A CXL region should exist if so after memdev allocation/initialization.
Get HPA from region and map it.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 22a7d1d95425..78f926300943 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -19,6 +19,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
struct efx_nic *efx = &probe_data->efx;
struct pci_dev *pci_dev = efx->pci_dev;
struct efx_cxl *cxl;
+ struct range range;
u16 dvsec;
int rc;
@@ -82,6 +83,24 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
return PTR_ERR(cxl->cxlmd);
}
+ cxl->cxled = cxl_get_committed_decoder(cxl->cxlmd, &cxl->efx_region);
+ if (!cxl->cxled || !cxl->efx_region)
+ return -ENODEV;
+
+ rc = cxl_get_region_range(cxl->efx_region, &range);
+ if (rc) {
+ pci_err(pci_dev,
+ "CXL getting regions params from a committed decoder failed");
+ return rc;
+ }
+
+ cxl->ctpio_cxl = ioremap(range.start, range_len(&range));
+ if (!cxl->ctpio_cxl) {
+ pci_err(pci_dev, "CXL ioremap region (%pra) failed", &range);
+ return -ENOMEM;
+ }
+
+
probe_data->cxl = cxl;
return 0;
@@ -89,6 +108,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
void efx_cxl_exit(struct efx_probe_data *probe_data)
{
+ if (!probe_data->cxl)
+ return;
+
+ iounmap(probe_data->cxl->ctpio_cxl);
+ cxl_unregister_region(probe_data->cxl->efx_region);
}
MODULE_IMPORT_NS("CXL");
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 10/11] cxl: Avoid dax creation for accelerators
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (8 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-25 2:59 ` Alison Schofield
2026-03-23 11:31 ` [PATCH v24 11/11] sfc: support pio mapping based on cxl alejandro.lucero-palau
10 siblings, 1 reply; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Jonathan Cameron, Davidlohr Bueso, Ben Cheatham
From: Alejandro Lucero <alucerop@amd.com>
By definition a type2 cxl device will use the host managed memory for
specific functionality, therefore it should not be available to other
uses.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Davidlohr Bueso <daves@stgolabs.net>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
---
drivers/cxl/core/region.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 8bb53a095290..2f9bdb4f1f4f 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -4263,6 +4263,13 @@ static int cxl_region_probe(struct device *dev)
if (rc)
return rc;
+ /*
+ * HDM-D[B] (device-memory) regions have accelerator specific usage.
+ * Skip device-dax registration.
+ */
+ if (cxlr->type == CXL_DECODER_DEVMEM)
+ return 0;
+
/*
* From this point on any path that changes the region's state away from
* CXL_CONFIG_COMMIT is also responsible for releasing the driver.
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v24 11/11] sfc: support pio mapping based on cxl
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
` (9 preceding siblings ...)
2026-03-23 11:31 ` [PATCH v24 10/11] cxl: Avoid dax creation for accelerators alejandro.lucero-palau
@ 2026-03-23 11:31 ` alejandro.lucero-palau
2026-03-23 22:18 ` Edward Cree
10 siblings, 1 reply; 29+ messages in thread
From: alejandro.lucero-palau @ 2026-03-23 11:31 UTC (permalink / raw)
To: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
Cc: Alejandro Lucero, Jonathan Cameron
From: Alejandro Lucero <alucerop@amd.com>
A PIO buffer is a region of device memory to which the driver can write a
packet for TX, with the device handling the transmit doorbell without
requiring a DMA for getting the packet data, which helps reducing latency
in certain exchanges. With CXL mem protocol this latency can be lowered
further.
With a device supporting CXL and successfully initialised, use the cxl
region to map the memory range and use this mapping for PIO buffers.
Add the disabling of those CXL-based PIO buffers if the callback for
potential cxl endpoint removal by the CXL code happens.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/net/ethernet/sfc/ef10.c | 53 +++++++++++++++++++++++----
drivers/net/ethernet/sfc/efx_cxl.c | 1 +
drivers/net/ethernet/sfc/net_driver.h | 2 +
drivers/net/ethernet/sfc/nic.h | 3 ++
4 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 7e04f115bbaa..ae422bac329e 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -24,6 +24,7 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <net/udp_tunnel.h>
+#include "efx_cxl.h"
/* Hardware control for EF10 architecture including 'Huntington'. */
@@ -106,7 +107,7 @@ static int efx_ef10_get_vf_index(struct efx_nic *efx)
static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
{
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V4_OUT_LEN);
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
struct efx_ef10_nic_data *nic_data = efx->nic_data;
size_t outlen;
int rc;
@@ -177,6 +178,12 @@ static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
efx->num_mac_stats);
}
+ if (outlen < MC_CMD_GET_CAPABILITIES_V7_OUT_LEN)
+ nic_data->datapath_caps3 = 0;
+ else
+ nic_data->datapath_caps3 = MCDI_DWORD(outbuf,
+ GET_CAPABILITIES_V7_OUT_FLAGS3);
+
return 0;
}
@@ -919,6 +926,9 @@ static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
static void efx_ef10_remove(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
+#ifdef CONFIG_SFC_CXL
+ struct efx_probe_data *probe_data;
+#endif
int rc;
#ifdef CONFIG_SFC_SRIOV
@@ -949,7 +959,12 @@ static void efx_ef10_remove(struct efx_nic *efx)
efx_mcdi_rx_free_indir_table(efx);
+#ifdef CONFIG_SFC_CXL
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+ if (nic_data->wc_membase && !probe_data->cxl_pio_in_use)
+#else
if (nic_data->wc_membase)
+#endif
iounmap(nic_data->wc_membase);
rc = efx_mcdi_free_vis(efx);
@@ -1140,6 +1155,9 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
unsigned int channel_vis, pio_write_vi_base, max_vis;
struct efx_ef10_nic_data *nic_data = efx->nic_data;
unsigned int uc_mem_map_size, wc_mem_map_size;
+#ifdef CONFIG_SFC_CXL
+ struct efx_probe_data *probe_data;
+#endif
void __iomem *membase;
int rc;
@@ -1263,8 +1281,28 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
iounmap(efx->membase);
efx->membase = membase;
- /* Set up the WC mapping if needed */
- if (wc_mem_map_size) {
+ if (!wc_mem_map_size)
+ goto skip_pio;
+
+ /* Set up the WC mapping */
+
+#ifdef CONFIG_SFC_CXL
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+ if ((nic_data->datapath_caps3 &
+ (1 << MC_CMD_GET_CAPABILITIES_V7_OUT_CXL_CONFIG_ENABLE_LBN)) &&
+ probe_data->cxl_pio_initialised) {
+ /* Using PIO through CXL mapping? */
+ nic_data->pio_write_base = probe_data->cxl->ctpio_cxl +
+ (pio_write_vi_base * efx->vi_stride +
+ ER_DZ_TX_PIOBUF - uc_mem_map_size);
+
+ nic_data->pio_write_vi_base = pio_write_vi_base;
+
+ probe_data->cxl_pio_in_use = true;
+ } else
+#endif
+ {
+ /* Using legacy PIO BAR mapping */
nic_data->wc_membase = ioremap_wc(efx->membase_phys +
uc_mem_map_size,
wc_mem_map_size);
@@ -1279,12 +1317,13 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
nic_data->wc_membase +
(pio_write_vi_base * efx->vi_stride + ER_DZ_TX_PIOBUF -
uc_mem_map_size);
-
- rc = efx_ef10_link_piobufs(efx);
- if (rc)
- efx_ef10_free_piobufs(efx);
}
+ rc = efx_ef10_link_piobufs(efx);
+ if (rc)
+ efx_ef10_free_piobufs(efx);
+
+skip_pio:
netif_dbg(efx, probe, efx->net_dev,
"memory BAR at %pa (virtual %p+%x UC, %p+%x WC)\n",
&efx->membase_phys, efx->membase, uc_mem_map_size,
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 78f926300943..ec614f9242b2 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -102,6 +102,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
probe_data->cxl = cxl;
+ probe_data->cxl_pio_initialised = true;
return 0;
}
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 3964b2c56609..bea4eecdf842 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1207,6 +1207,7 @@ struct efx_cxl;
* @efx: Efx NIC details
* @cxl: details of related cxl objects
* @cxl_pio_initialised: cxl initialization outcome.
+ * @cxl_pio_in_use: PIO using CXL mapping
*/
struct efx_probe_data {
struct pci_dev *pci_dev;
@@ -1214,6 +1215,7 @@ struct efx_probe_data {
#ifdef CONFIG_SFC_CXL
struct efx_cxl *cxl;
bool cxl_pio_initialised;
+ bool cxl_pio_in_use;
#endif
};
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index ec3b2df43b68..7480f9995dfb 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -152,6 +152,8 @@ enum {
* %MC_CMD_GET_CAPABILITIES response)
* @datapath_caps2: Further Capabilities of datapath firmware (FLAGS2 field of
* %MC_CMD_GET_CAPABILITIES response)
+ * @datapath_caps3: Further Capabilities of datapath firmware (FLAGS3 field of
+ * %MC_CMD_GET_CAPABILITIES response)
* @rx_dpcpu_fw_id: Firmware ID of the RxDPCPU
* @tx_dpcpu_fw_id: Firmware ID of the TxDPCPU
* @must_probe_vswitching: Flag: vswitching has yet to be setup after MC reboot
@@ -187,6 +189,7 @@ struct efx_ef10_nic_data {
bool must_check_datapath_caps;
u32 datapath_caps;
u32 datapath_caps2;
+ u32 datapath_caps3;
unsigned int rx_dpcpu_fw_id;
unsigned int tx_dpcpu_fw_id;
bool must_probe_vswitching;
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH v24 11/11] sfc: support pio mapping based on cxl
2026-03-23 11:31 ` [PATCH v24 11/11] sfc: support pio mapping based on cxl alejandro.lucero-palau
@ 2026-03-23 22:18 ` Edward Cree
0 siblings, 0 replies; 29+ messages in thread
From: Edward Cree @ 2026-03-23 22:18 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dave.jiang,
dan.j.williams, edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero, Jonathan Cameron
On 23/03/2026 11:31, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> A PIO buffer is a region of device memory to which the driver can write a
> packet for TX, with the device handling the transmit doorbell without
> requiring a DMA for getting the packet data, which helps reducing latency
> in certain exchanges. With CXL mem protocol this latency can be lowered
> further.
>
> With a device supporting CXL and successfully initialised, use the cxl
> region to map the memory range and use this mapping for PIO buffers.
>
> Add the disabling of those CXL-based PIO buffers if the callback for
> potential cxl endpoint removal by the CXL code happens.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 01/11] sfc: add cxl support
2026-03-23 11:31 ` [PATCH v24 01/11] sfc: add cxl support alejandro.lucero-palau
@ 2026-03-24 16:29 ` Jonathan Cameron
2026-03-24 21:05 ` Alejandro Lucero Palau
0 siblings, 1 reply; 29+ messages in thread
From: Jonathan Cameron @ 2026-03-24 16:29 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Alejandro Lucero, Edward Cree,
Alison Schofield
On Mon, 23 Mar 2026 11:31:07 +0000
<alejandro.lucero-palau@amd.com> wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Add CXL initialization based on new CXL API for accel drivers and make
> it dependent on kernel CXL configuration.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
> Reviewed-by: Alison Schofield <alison.schofield@intel.com>
> Reviewed-by: Dan Williams <dan.j.williams@intel.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Hi Alejandro,
Been a while since I looked at this, so I may well repeat earlier discussions!
One really minor thing inline.
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> new file mode 100644
> index 000000000000..8e0481d8dced
> --- /dev/null
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/****************************************************************************
> + *
> + * Driver for AMD network controllers and boards
> + * Copyright (C) 2025, Advanced Micro Devices, Inc.
> + */
> +
> +#include <linux/pci.h>
> +
> +#include "net_driver.h"
> +#include "efx_cxl.h"
> +
> +#define EFX_CTPIO_BUFFER_SIZE SZ_256M
> +
> +int efx_cxl_init(struct efx_probe_data *probe_data)
> +{
> + struct efx_nic *efx = &probe_data->efx;
> + struct pci_dev *pci_dev = efx->pci_dev;
> + struct efx_cxl *cxl;
> + u16 dvsec;
> +
> + probe_data->cxl_pio_initialised = false;
> +
> + /* Is the device configured with and using CXL? */
> + if (!pcie_is_cxl(pci_dev))
> + return 0;
> +
> + dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
> + PCI_DVSEC_CXL_DEVICE);
> + if (!dvsec) {
> + pci_err(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability not found\n");
Trivial but if we are returning zero is it always an error?
Maybe pci_info() more appropriate?
> + return 0;
> + }
> +
> + pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
> +
> + /* Create a cxl_dev_state embedded in the cxl struct using cxl core api
> + * specifying no mbox available.
> + */
> + cxl = devm_cxl_dev_state_create(&pci_dev->dev, CXL_DEVTYPE_DEVMEM,
> + pci_dev->dev.id, dvsec, struct efx_cxl,
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 02/11] cxl/sfc: Map cxl regs
2026-03-23 11:31 ` [PATCH v24 02/11] cxl/sfc: Map cxl regs alejandro.lucero-palau
@ 2026-03-24 16:33 ` Jonathan Cameron
2026-03-24 21:06 ` Alejandro Lucero Palau
0 siblings, 1 reply; 29+ messages in thread
From: Jonathan Cameron @ 2026-03-24 16:33 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Alejandro Lucero, Ben Cheatham,
Edward Cree
On Mon, 23 Mar 2026 11:31:08 +0000
alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Export cxl core functions for a Type2 driver being able to discover and
> map the device registers.
>
> Use it in sfc driver cxl initialization.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Reviewed-by: Dan Williams <dan.j.williams@intel.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
One trivial thing that you might want to tidy up.
Thanks,
Jonathan
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> index 8e0481d8dced..7917118e4eba 100644
> --- a/drivers/net/ethernet/sfc/efx_cxl.c
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -7,6 +7,8 @@
>
> #include <linux/pci.h>
>
> +#include <cxl/cxl.h>
> +#include <cxl/pci.h>
> #include "net_driver.h"
> #include "efx_cxl.h"
>
> @@ -18,6 +20,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> struct pci_dev *pci_dev = efx->pci_dev;
> struct efx_cxl *cxl;
> u16 dvsec;
> + int rc;
>
> probe_data->cxl_pio_initialised = false;
>
> @@ -44,6 +47,30 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> if (!cxl)
> return -ENOMEM;
>
> + rc = cxl_pci_setup_regs(pci_dev, CXL_REGLOC_RBI_COMPONENT,
> + &cxl->cxlds.reg_map);
> + if (rc) {
> + pci_err(pci_dev, "No component registers\n");
> + return rc;
> + }
> +
> + if (!cxl->cxlds.reg_map.component_map.hdm_decoder.valid) {
> + pci_err(pci_dev, "Expected HDM component register not found\n");
> + return -ENODEV;
> + }
> +
> + if (!cxl->cxlds.reg_map.component_map.ras.valid) {
> + pci_err(pci_dev, "Expected RAS component register not found\n");
> + return -ENODEV;
> + }
> +
> + /*
Networking code. So wrong style.
Ah the fun of patches that touch drivers/net and drivers/cxl :)
> + * Set media ready explicitly as there are neither mailbox for checking
> + * this state nor the CXL register involved, both not mandatory for
> + * type2.
> + */
> + cxl->cxlds.media_ready = true;
> +
> probe_data->cxl = cxl;
>
> return 0;
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder
2026-03-23 11:31 ` [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder alejandro.lucero-palau
@ 2026-03-24 16:48 ` Jonathan Cameron
2026-03-24 21:20 ` Alejandro Lucero Palau
2026-03-24 17:32 ` Dave Jiang
1 sibling, 1 reply; 29+ messages in thread
From: Jonathan Cameron @ 2026-03-24 16:48 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Alejandro Lucero
On Mon, 23 Mar 2026 11:31:12 +0000
alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> A Type2 device configured by the BIOS can already have its HDM
> committed. Add a cxl_get_committed_decoder() function for cheking
Spell check commit messages. checking if there is one
> so after memdev creation. A CXL region should have been created
> during memdev initialization, therefore a Type2 driver can ask for
> such a region for working with the HPA. If the HDM is not committed,
> a Type2 driver will create the region after obtaining proper HPA
> and DPA space.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
I'm not following the logic below. Perhaps some comments would help
me understand why the condition is sufficient.
> ---
> drivers/cxl/core/hdm.c | 39 +++++++++++++++++++++++++++++++++++++++
> include/cxl/cxl.h | 3 +++
> 2 files changed, 42 insertions(+)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index c222e98ae736..006be88efaa5 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -686,6 +686,45 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
> return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
> }
>
> +static int find_committed_endpoint_decoder(struct device *dev, const void *data)
> +{
> + struct cxl_endpoint_decoder *cxled;
> + struct cxl_port *port;
> +
> + if (!is_endpoint_decoder(dev))
> + return 0;
> +
> + cxled = to_cxl_endpoint_decoder(dev);
> + port = cxled_to_port(cxled);
> +
> + return cxled->cxld.id == port->hdm_end;
This condition is non obvious enough that to me it maybe needs a comment on
why it works.
> +}
> +
> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
> + struct cxl_region **cxlr)
> +{
> + struct cxl_port *endpoint = cxlmd->endpoint;
> + struct cxl_endpoint_decoder *cxled;
> + struct device *cxled_dev;
> +
> + if (!endpoint)
> + return NULL;
> +
> + guard(rwsem_read)(&cxl_rwsem.dpa);
struct device *cxled_dev __free(device) =
device_find_child(&...)
or something along those lines to avoid need for manual put below.
> + cxled_dev = device_find_child(&endpoint->dev, NULL,
> + find_committed_endpoint_decoder);
> +
> + if (!cxled_dev)
> + return NULL;
> +
> + cxled = to_cxl_endpoint_decoder(cxled_dev);
> + *cxlr = cxled->cxld.region;
> +
> + put_device(cxled_dev);
> + return cxled;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_get_committed_decoder, "CXL");
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators
2026-03-23 11:31 ` [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators alejandro.lucero-palau
@ 2026-03-24 16:50 ` Jonathan Cameron
2026-03-24 21:36 ` Alejandro Lucero Palau
0 siblings, 1 reply; 29+ messages in thread
From: Jonathan Cameron @ 2026-03-24 16:50 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Alejandro Lucero, Gregory Price
On Mon, 23 Mar 2026 11:31:14 +0000
alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Add cxl_unregister_region() to the accelerator driver API
> for a clean exit.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
For this I'm seeing an outstanding question from Gregory on v23.
> ---
> drivers/cxl/core/region.c | 17 ++++++++++++-----
> include/cxl/cxl.h | 1 +
> 2 files changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 9c3ba911d865..8bb53a095290 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -2468,9 +2468,8 @@ static struct cxl_region *to_cxl_region(struct device *dev)
> return container_of(dev, struct cxl_region, dev);
> }
>
> -static void unregister_region(void *_cxlr)
> +void cxl_unregister_region(struct cxl_region *cxlr)
> {
> - struct cxl_region *cxlr = _cxlr;
> struct cxl_region_params *p = &cxlr->params;
> int i;
>
> @@ -2489,6 +2488,14 @@ static void unregister_region(void *_cxlr)
> cxl_region_iomem_release(cxlr);
> put_device(&cxlr->dev);
> }
> +EXPORT_SYMBOL_NS_GPL(cxl_unregister_region, "CXL");
> +
> +static void __unregister_region(void *_cxlr)
> +{
> + struct cxl_region *cxlr = _cxlr;
> +
> + return cxl_unregister_region(cxlr);
> +}
>
> static struct lock_class_key cxl_region_key;
>
> @@ -2642,7 +2649,7 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
> if (rc)
> goto err;
>
> - rc = devm_add_action_or_reset(port->uport_dev, unregister_region, cxlr);
> + rc = devm_add_action_or_reset(port->uport_dev, __unregister_region, cxlr);
> if (rc)
> return ERR_PTR(rc);
>
> @@ -2797,7 +2804,7 @@ static ssize_t delete_region_store(struct device *dev,
> if (IS_ERR(cxlr))
> return PTR_ERR(cxlr);
>
> - devm_release_action(port->uport_dev, unregister_region, cxlr);
> + devm_release_action(port->uport_dev, __unregister_region, cxlr);
> put_device(&cxlr->dev);
>
> return len;
> @@ -3963,7 +3970,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>
> rc = __construct_region(cxlr, ctx);
> if (rc) {
> - devm_release_action(port->uport_dev, unregister_region, cxlr);
> + devm_release_action(port->uport_dev, __unregister_region, cxlr);
> return ERR_PTR(rc);
> }
>
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 122b3331469d..b8cdc604480a 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -236,4 +236,5 @@ struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
> struct cxl_region **cxlr);
> struct range;
> int cxl_get_region_range(struct cxl_region *region, struct range *range);
> +void cxl_unregister_region(struct cxl_region *cxlr);
> #endif /* __CXL_CXL_H__ */
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware
2026-03-23 11:31 ` [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware alejandro.lucero-palau
@ 2026-03-24 16:56 ` Jonathan Cameron
2026-03-24 21:43 ` Alejandro Lucero Palau
2026-03-24 17:38 ` Dave Jiang
1 sibling, 1 reply; 29+ messages in thread
From: Jonathan Cameron @ 2026-03-24 16:56 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Alejandro Lucero, Edward Cree
On Mon, 23 Mar 2026 11:31:15 +0000
alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Check if device HDM is already committed during firmware/BIOS
> initialization.
>
> A CXL region should exist if so after memdev allocation/initialization.
> Get HPA from region and map it.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
> ---
> drivers/net/ethernet/sfc/efx_cxl.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> index 22a7d1d95425..78f926300943 100644
> --- a/drivers/net/ethernet/sfc/efx_cxl.c
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -19,6 +19,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> struct efx_nic *efx = &probe_data->efx;
> struct pci_dev *pci_dev = efx->pci_dev;
> struct efx_cxl *cxl;
> + struct range range;
> u16 dvsec;
> int rc;
>
> @@ -82,6 +83,24 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> return PTR_ERR(cxl->cxlmd);
> }
>
> + cxl->cxled = cxl_get_committed_decoder(cxl->cxlmd, &cxl->efx_region);
> + if (!cxl->cxled || !cxl->efx_region)
> + return -ENODEV;
> +
> + rc = cxl_get_region_range(cxl->efx_region, &range);
> + if (rc) {
> + pci_err(pci_dev,
> + "CXL getting regions params from a committed decoder failed");
> + return rc;
> + }
> +
> + cxl->ctpio_cxl = ioremap(range.start, range_len(&range));
> + if (!cxl->ctpio_cxl) {
> + pci_err(pci_dev, "CXL ioremap region (%pra) failed", &range);
> + return -ENOMEM;
> + }
> +
> +
> probe_data->cxl = cxl;
>
> return 0;
> @@ -89,6 +108,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>
> void efx_cxl_exit(struct efx_probe_data *probe_data)
> {
> + if (!probe_data->cxl)
> + return;
> +
> + iounmap(probe_data->cxl->ctpio_cxl);
> + cxl_unregister_region(probe_data->cxl->efx_region);
When something called cxl_unregister_region() is called in exit() I look for
where cxl_register_region() is.... and I can't find it (more than possible
I'm failing to search the code though! What is this undoing?
> }
>
> MODULE_IMPORT_NS("CXL");
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder
2026-03-23 11:31 ` [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder alejandro.lucero-palau
2026-03-24 16:48 ` Jonathan Cameron
@ 2026-03-24 17:32 ` Dave Jiang
2026-03-24 21:55 ` Alejandro Lucero Palau
1 sibling, 1 reply; 29+ messages in thread
From: Dave Jiang @ 2026-03-24 17:32 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero
On 3/23/26 4:31 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
Maybe subject should be "Add helper function to retrieve a committed decoder and its region"?
> A Type2 device configured by the BIOS can already have its HDM
> committed. Add a cxl_get_committed_decoder() function for cheking
> so after memdev creation. A CXL region should have been created
Sentence doesn't quite make sense to me.
> during memdev initialization, therefore a Type2 driver can ask for
> such a region for working with the HPA. If the HDM is not committed,
> a Type2 driver will create the region after obtaining proper HPA
> and DPA space.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/hdm.c | 39 +++++++++++++++++++++++++++++++++++++++
> include/cxl/cxl.h | 3 +++
> 2 files changed, 42 insertions(+)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index c222e98ae736..006be88efaa5 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -686,6 +686,45 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
> return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
> }
>
> +static int find_committed_endpoint_decoder(struct device *dev, const void *data)
> +{
> + struct cxl_endpoint_decoder *cxled;
> + struct cxl_port *port;
> +
> + if (!is_endpoint_decoder(dev))
> + return 0;
> +
> + cxled = to_cxl_endpoint_decoder(dev);
> + port = cxled_to_port(cxled);
> +
> + return cxled->cxld.id == port->hdm_end;
> +}
> +
> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
> + struct cxl_region **cxlr)
kdoc header for this exported function?
> +{
> + struct cxl_port *endpoint = cxlmd->endpoint;
> + struct cxl_endpoint_decoder *cxled;
> + struct device *cxled_dev;
> +
> + if (!endpoint)
> + return NULL;
> +
> + guard(rwsem_read)(&cxl_rwsem.dpa);
> + cxled_dev = device_find_child(&endpoint->dev, NULL,
> + find_committed_endpoint_decoder);
> +
> + if (!cxled_dev)
> + return NULL;
> +
> + cxled = to_cxl_endpoint_decoder(cxled_dev);
> + *cxlr = cxled->cxld.region;
Should SFC take a ref on the region device?
> +
> + put_device(cxled_dev);
Maybe should let the caller release the reference? I think you will want to hold the reference by SFC until you no longer need the decoder?
DJ
> + return cxled;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_get_committed_decoder, "CXL");
> +
> static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
> {
> u16 eig;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 10a9b8fa2f6b..2a61138e2a73 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -231,4 +231,7 @@ struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev,
> int cxl_set_capacity(struct cxl_dev_state *cxlds, u64 capacity);
> struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
> const struct cxl_memdev_attach *attach);
> +struct cxl_region;
> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
> + struct cxl_region **cxlr);
> #endif /* __CXL_CXL_H__ */
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware
2026-03-23 11:31 ` [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware alejandro.lucero-palau
2026-03-24 16:56 ` Jonathan Cameron
@ 2026-03-24 17:38 ` Dave Jiang
2026-03-24 22:02 ` Alejandro Lucero Palau
1 sibling, 1 reply; 29+ messages in thread
From: Dave Jiang @ 2026-03-24 17:38 UTC (permalink / raw)
To: alejandro.lucero-palau, linux-cxl, netdev, dan.j.williams,
edward.cree, davem, kuba, pabeni, edumazet
Cc: Alejandro Lucero, Edward Cree
On 3/23/26 4:31 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> Check if device HDM is already committed during firmware/BIOS
> initialization.
>
> A CXL region should exist if so after memdev allocation/initialization.
> Get HPA from region and map it.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
> ---
> drivers/net/ethernet/sfc/efx_cxl.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> index 22a7d1d95425..78f926300943 100644
> --- a/drivers/net/ethernet/sfc/efx_cxl.c
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -19,6 +19,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> struct efx_nic *efx = &probe_data->efx;
> struct pci_dev *pci_dev = efx->pci_dev;
> struct efx_cxl *cxl;
> + struct range range;
> u16 dvsec;
> int rc;
>
> @@ -82,6 +83,24 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> return PTR_ERR(cxl->cxlmd);
> }
>
> + cxl->cxled = cxl_get_committed_decoder(cxl->cxlmd, &cxl->efx_region);
> + if (!cxl->cxled || !cxl->efx_region)
> + return -ENODEV;
> +
> + rc = cxl_get_region_range(cxl->efx_region, &range);
> + if (rc) {
> + pci_err(pci_dev,
> + "CXL getting regions params from a committed decoder failed");
> + return rc;
> + }
> +
> + cxl->ctpio_cxl = ioremap(range.start, range_len(&range));
> + if (!cxl->ctpio_cxl) {
> + pci_err(pci_dev, "CXL ioremap region (%pra) failed", &range);
> + return -ENOMEM;
> + }
> +
> +
> probe_data->cxl = cxl;
>
> return 0;
> @@ -89,6 +108,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>
> void efx_cxl_exit(struct efx_probe_data *probe_data)
> {
> + if (!probe_data->cxl)
> + return;
> +
> + iounmap(probe_data->cxl->ctpio_cxl);
> + cxl_unregister_region(probe_data->cxl->efx_region);
Would a device_put() on the region dev be sufficient here? Not sure if everything should be torn down if SFC didn't create the region to begin with and only retrieved it via cxl_get_commited_decoder()?
DJ
> }
>
> MODULE_IMPORT_NS("CXL");
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 01/11] sfc: add cxl support
2026-03-24 16:29 ` Jonathan Cameron
@ 2026-03-24 21:05 ` Alejandro Lucero Palau
0 siblings, 0 replies; 29+ messages in thread
From: Alejandro Lucero Palau @ 2026-03-24 21:05 UTC (permalink / raw)
To: Jonathan Cameron, alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Edward Cree, Alison Schofield
On 3/24/26 16:29, Jonathan Cameron wrote:
> On Mon, 23 Mar 2026 11:31:07 +0000
> <alejandro.lucero-palau@amd.com> wrote:
>
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Add CXL initialization based on new CXL API for accel drivers and make
>> it dependent on kernel CXL configuration.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
>> Reviewed-by: Alison Schofield <alison.schofield@intel.com>
>> Reviewed-by: Dan Williams <dan.j.williams@intel.com>
>> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> Hi Alejandro,
>
> Been a while since I looked at this, so I may well repeat earlier discussions!
>
> One really minor thing inline.
>
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
>> new file mode 100644
>> index 000000000000..8e0481d8dced
>> --- /dev/null
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
>> @@ -0,0 +1,56 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/****************************************************************************
>> + *
>> + * Driver for AMD network controllers and boards
>> + * Copyright (C) 2025, Advanced Micro Devices, Inc.
>> + */
>> +
>> +#include <linux/pci.h>
>> +
>> +#include "net_driver.h"
>> +#include "efx_cxl.h"
>> +
>> +#define EFX_CTPIO_BUFFER_SIZE SZ_256M
>> +
>> +int efx_cxl_init(struct efx_probe_data *probe_data)
>> +{
>> + struct efx_nic *efx = &probe_data->efx;
>> + struct pci_dev *pci_dev = efx->pci_dev;
>> + struct efx_cxl *cxl;
>> + u16 dvsec;
>> +
>> + probe_data->cxl_pio_initialised = false;
>> +
>> + /* Is the device configured with and using CXL? */
>> + if (!pcie_is_cxl(pci_dev))
>> + return 0;
>> +
>> + dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
>> + PCI_DVSEC_CXL_DEVICE);
>> + if (!dvsec) {
>> + pci_err(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability not found\n");
> Trivial but if we are returning zero is it always an error?
> Maybe pci_info() more appropriate?
It makes sense. I'll change it.
Thanks!
>> + return 0;
>> + }
>> +
>> + pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
>> +
>> + /* Create a cxl_dev_state embedded in the cxl struct using cxl core api
>> + * specifying no mbox available.
>> + */
>> + cxl = devm_cxl_dev_state_create(&pci_dev->dev, CXL_DEVTYPE_DEVMEM,
>> + pci_dev->dev.id, dvsec, struct efx_cxl,
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 02/11] cxl/sfc: Map cxl regs
2026-03-24 16:33 ` Jonathan Cameron
@ 2026-03-24 21:06 ` Alejandro Lucero Palau
0 siblings, 0 replies; 29+ messages in thread
From: Alejandro Lucero Palau @ 2026-03-24 21:06 UTC (permalink / raw)
To: Jonathan Cameron, alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Ben Cheatham, Edward Cree
On 3/24/26 16:33, Jonathan Cameron wrote:
> On Mon, 23 Mar 2026 11:31:08 +0000
> alejandro.lucero-palau@amd.com wrote:
>
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Export cxl core functions for a Type2 driver being able to discover and
>> map the device registers.
>>
>> Use it in sfc driver cxl initialization.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Reviewed-by: Dan Williams <dan.j.williams@intel.com>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
>> Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
>> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
> One trivial thing that you might want to tidy up.
>
> Thanks,
>
> Jonathan
>
>
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
>> index 8e0481d8dced..7917118e4eba 100644
>> --- a/drivers/net/ethernet/sfc/efx_cxl.c
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
>> @@ -7,6 +7,8 @@
>>
>> #include <linux/pci.h>
>>
>> +#include <cxl/cxl.h>
>> +#include <cxl/pci.h>
>> #include "net_driver.h"
>> #include "efx_cxl.h"
>>
>> @@ -18,6 +20,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> struct pci_dev *pci_dev = efx->pci_dev;
>> struct efx_cxl *cxl;
>> u16 dvsec;
>> + int rc;
>>
>> probe_data->cxl_pio_initialised = false;
>>
>> @@ -44,6 +47,30 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> if (!cxl)
>> return -ENOMEM;
>>
>> + rc = cxl_pci_setup_regs(pci_dev, CXL_REGLOC_RBI_COMPONENT,
>> + &cxl->cxlds.reg_map);
>> + if (rc) {
>> + pci_err(pci_dev, "No component registers\n");
>> + return rc;
>> + }
>> +
>> + if (!cxl->cxlds.reg_map.component_map.hdm_decoder.valid) {
>> + pci_err(pci_dev, "Expected HDM component register not found\n");
>> + return -ENODEV;
>> + }
>> +
>> + if (!cxl->cxlds.reg_map.component_map.ras.valid) {
>> + pci_err(pci_dev, "Expected RAS component register not found\n");
>> + return -ENODEV;
>> + }
>> +
>> + /*
> Networking code. So wrong style.
>
> Ah the fun of patches that touch drivers/net and drivers/cxl :)
Good catch.
I'll fix it.
Thanks!
>> + * Set media ready explicitly as there are neither mailbox for checking
>> + * this state nor the CXL register involved, both not mandatory for
>> + * type2.
>> + */
>> + cxl->cxlds.media_ready = true;
>> +
>> probe_data->cxl = cxl;
>>
>> return 0;
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder
2026-03-24 16:48 ` Jonathan Cameron
@ 2026-03-24 21:20 ` Alejandro Lucero Palau
0 siblings, 0 replies; 29+ messages in thread
From: Alejandro Lucero Palau @ 2026-03-24 21:20 UTC (permalink / raw)
To: Jonathan Cameron, alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet
On 3/24/26 16:48, Jonathan Cameron wrote:
> On Mon, 23 Mar 2026 11:31:12 +0000
> alejandro.lucero-palau@amd.com wrote:
>
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> A Type2 device configured by the BIOS can already have its HDM
>> committed. Add a cxl_get_committed_decoder() function for cheking
> Spell check commit messages. checking if there is one
>
:-)
I'll fix it.
>> so after memdev creation. A CXL region should have been created
>> during memdev initialization, therefore a Type2 driver can ask for
>> such a region for working with the HPA. If the HDM is not committed,
>> a Type2 driver will create the region after obtaining proper HPA
>> and DPA space.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> I'm not following the logic below. Perhaps some comments would help
> me understand why the condition is sufficient.
>
>> ---
>> drivers/cxl/core/hdm.c | 39 +++++++++++++++++++++++++++++++++++++++
>> include/cxl/cxl.h | 3 +++
>> 2 files changed, 42 insertions(+)
>>
>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
>> index c222e98ae736..006be88efaa5 100644
>> --- a/drivers/cxl/core/hdm.c
>> +++ b/drivers/cxl/core/hdm.c
>> @@ -686,6 +686,45 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
>> return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
>> }
>>
>> +static int find_committed_endpoint_decoder(struct device *dev, const void *data)
>> +{
>> + struct cxl_endpoint_decoder *cxled;
>> + struct cxl_port *port;
>> +
>> + if (!is_endpoint_decoder(dev))
>> + return 0;
>> +
>> + cxled = to_cxl_endpoint_decoder(dev);
>> + port = cxled_to_port(cxled);
>> +
>> + return cxled->cxld.id == port->hdm_end;
> This condition is non obvious enough that to me it maybe needs a comment on
> why it works.
Uhmm, yes, that works but because I check such a decoder is linked to a
region inside the sfc driver.
Benjamin Cheatham pointed out the weakness of this and I did a bad job
trying to improve it
.
I think I should check here the decoder state and if a region was auto
discovered based in such a decoder instead than by the driver.
I will fix it.
Thanks.
>> +}
>> +
>> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
>> + struct cxl_region **cxlr)
>> +{
>> + struct cxl_port *endpoint = cxlmd->endpoint;
>> + struct cxl_endpoint_decoder *cxled;
>> + struct device *cxled_dev;
>> +
>> + if (!endpoint)
>> + return NULL;
>> +
>> + guard(rwsem_read)(&cxl_rwsem.dpa);
> struct device *cxled_dev __free(device) =
> device_find_child(&...)
>
> or something along those lines to avoid need for manual put below.
>
>> + cxled_dev = device_find_child(&endpoint->dev, NULL,
>> + find_committed_endpoint_decoder);
>> +
>> + if (!cxled_dev)
>> + return NULL;
>> +
>> + cxled = to_cxl_endpoint_decoder(cxled_dev);
>> + *cxlr = cxled->cxld.region;
>> +
>> + put_device(cxled_dev);
>> + return cxled;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_get_committed_decoder, "CXL");
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators
2026-03-24 16:50 ` Jonathan Cameron
@ 2026-03-24 21:36 ` Alejandro Lucero Palau
2026-03-26 21:28 ` Cheatham, Benjamin
0 siblings, 1 reply; 29+ messages in thread
From: Alejandro Lucero Palau @ 2026-03-24 21:36 UTC (permalink / raw)
To: Jonathan Cameron, alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Gregory Price
On 3/24/26 16:50, Jonathan Cameron wrote:
> On Mon, 23 Mar 2026 11:31:14 +0000
> alejandro.lucero-palau@amd.com wrote:
>
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Add cxl_unregister_region() to the accelerator driver API
>> for a clean exit.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> For this I'm seeing an outstanding question from Gregory on v23.
Yes, I did not forget about it but I forgot to comment back.
The kreview is obviously wrong but I think it points out to the missing
invocation I need to add. I did not suffer those problems Gregory
mentions, but I think that is due to how I configure my testing kernel.
So, yes, I need to remove the release action from inside this function
to avoid invoking ... this same function. That is another thing that
puzzled me when I saw that review, and it implies I need to have
different functions for accelerator driver specific invocation and for
normal release action call. Or maybe just an extra param only removing
the devm release action if invoked by accelerators. I think I will go
with this last one. Any suggestion?
Thank you
>> ---
>> drivers/cxl/core/region.c | 17 ++++++++++++-----
>> include/cxl/cxl.h | 1 +
>> 2 files changed, 13 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
>> index 9c3ba911d865..8bb53a095290 100644
>> --- a/drivers/cxl/core/region.c
>> +++ b/drivers/cxl/core/region.c
>> @@ -2468,9 +2468,8 @@ static struct cxl_region *to_cxl_region(struct device *dev)
>> return container_of(dev, struct cxl_region, dev);
>> }
>>
>> -static void unregister_region(void *_cxlr)
>> +void cxl_unregister_region(struct cxl_region *cxlr)
>> {
>> - struct cxl_region *cxlr = _cxlr;
>> struct cxl_region_params *p = &cxlr->params;
>> int i;
>>
>> @@ -2489,6 +2488,14 @@ static void unregister_region(void *_cxlr)
>> cxl_region_iomem_release(cxlr);
>> put_device(&cxlr->dev);
>> }
>> +EXPORT_SYMBOL_NS_GPL(cxl_unregister_region, "CXL");
>> +
>> +static void __unregister_region(void *_cxlr)
>> +{
>> + struct cxl_region *cxlr = _cxlr;
>> +
>> + return cxl_unregister_region(cxlr);
>> +}
>>
>> static struct lock_class_key cxl_region_key;
>>
>> @@ -2642,7 +2649,7 @@ static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
>> if (rc)
>> goto err;
>>
>> - rc = devm_add_action_or_reset(port->uport_dev, unregister_region, cxlr);
>> + rc = devm_add_action_or_reset(port->uport_dev, __unregister_region, cxlr);
>> if (rc)
>> return ERR_PTR(rc);
>>
>> @@ -2797,7 +2804,7 @@ static ssize_t delete_region_store(struct device *dev,
>> if (IS_ERR(cxlr))
>> return PTR_ERR(cxlr);
>>
>> - devm_release_action(port->uport_dev, unregister_region, cxlr);
>> + devm_release_action(port->uport_dev, __unregister_region, cxlr);
>> put_device(&cxlr->dev);
>>
>> return len;
>> @@ -3963,7 +3970,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
>>
>> rc = __construct_region(cxlr, ctx);
>> if (rc) {
>> - devm_release_action(port->uport_dev, unregister_region, cxlr);
>> + devm_release_action(port->uport_dev, __unregister_region, cxlr);
>> return ERR_PTR(rc);
>> }
>>
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 122b3331469d..b8cdc604480a 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -236,4 +236,5 @@ struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
>> struct cxl_region **cxlr);
>> struct range;
>> int cxl_get_region_range(struct cxl_region *region, struct range *range);
>> +void cxl_unregister_region(struct cxl_region *cxlr);
>> #endif /* __CXL_CXL_H__ */
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware
2026-03-24 16:56 ` Jonathan Cameron
@ 2026-03-24 21:43 ` Alejandro Lucero Palau
0 siblings, 0 replies; 29+ messages in thread
From: Alejandro Lucero Palau @ 2026-03-24 21:43 UTC (permalink / raw)
To: Jonathan Cameron, alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Edward Cree
On 3/24/26 16:56, Jonathan Cameron wrote:
> On Mon, 23 Mar 2026 11:31:15 +0000
> alejandro.lucero-palau@amd.com wrote:
>
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Check if device HDM is already committed during firmware/BIOS
>> initialization.
>>
>> A CXL region should exist if so after memdev allocation/initialization.
>> Get HPA from region and map it.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
>> ---
>> drivers/net/ethernet/sfc/efx_cxl.c | 24 ++++++++++++++++++++++++
>> 1 file changed, 24 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
>> index 22a7d1d95425..78f926300943 100644
>> --- a/drivers/net/ethernet/sfc/efx_cxl.c
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
>> @@ -19,6 +19,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> struct efx_nic *efx = &probe_data->efx;
>> struct pci_dev *pci_dev = efx->pci_dev;
>> struct efx_cxl *cxl;
>> + struct range range;
>> u16 dvsec;
>> int rc;
>>
>> @@ -82,6 +83,24 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> return PTR_ERR(cxl->cxlmd);
>> }
>>
>> + cxl->cxled = cxl_get_committed_decoder(cxl->cxlmd, &cxl->efx_region);
>> + if (!cxl->cxled || !cxl->efx_region)
>> + return -ENODEV;
>> +
>> + rc = cxl_get_region_range(cxl->efx_region, &range);
>> + if (rc) {
>> + pci_err(pci_dev,
>> + "CXL getting regions params from a committed decoder failed");
>> + return rc;
>> + }
>> +
>> + cxl->ctpio_cxl = ioremap(range.start, range_len(&range));
>> + if (!cxl->ctpio_cxl) {
>> + pci_err(pci_dev, "CXL ioremap region (%pra) failed", &range);
>> + return -ENOMEM;
>> + }
>> +
>> +
>> probe_data->cxl = cxl;
>>
>> return 0;
>> @@ -89,6 +108,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>>
>> void efx_cxl_exit(struct efx_probe_data *probe_data)
>> {
>> + if (!probe_data->cxl)
>> + return;
>> +
>> + iounmap(probe_data->cxl->ctpio_cxl);
>> + cxl_unregister_region(probe_data->cxl->efx_region);
> When something called cxl_unregister_region() is called in exit() I look for
> where cxl_register_region() is.... and I can't find it (more than possible
> I'm failing to search the code though! What is this undoing?
It obviously requires a comment for avoiding this confusion. The region
is auto discovered when memdev is created:
memdev->port->hdm->region
so if the sfc cxl initialization was successful, it implies the endpoint
decoder has an auto discover region which is the one we need to remove
on exit, otherwise the region will be around until the root port is
removed. That is something that maybe should change likely linking the
region release to the endpoint memdev removal.
I will add such a comment.
Thank you
>
>> }
>>
>> MODULE_IMPORT_NS("CXL");
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder
2026-03-24 17:32 ` Dave Jiang
@ 2026-03-24 21:55 ` Alejandro Lucero Palau
0 siblings, 0 replies; 29+ messages in thread
From: Alejandro Lucero Palau @ 2026-03-24 21:55 UTC (permalink / raw)
To: Dave Jiang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, edward.cree, davem, kuba, pabeni, edumazet
On 3/24/26 17:32, Dave Jiang wrote:
>
> On 3/23/26 4:31 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
> Maybe subject should be "Add helper function to retrieve a committed decoder and its region"?
Uhmm, now that you point this out, I think I do not need the endpoint
decoder at all, just the region.
I'll do so and change the commit message accordingly.
>
>> A Type2 device configured by the BIOS can already have its HDM
>> committed. Add a cxl_get_committed_decoder() function for cheking
>> so after memdev creation. A CXL region should have been created
> Sentence doesn't quite make sense to me.
I will adjust it for the mentioned change. I also realize that I did not
remove the reference below to the other potential path if no committed
decoder.
>
>> during memdev initialization, therefore a Type2 driver can ask for
>> such a region for working with the HPA. If the HDM is not committed,
>> a Type2 driver will create the region after obtaining proper HPA
>> and DPA space.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> ---
>> drivers/cxl/core/hdm.c | 39 +++++++++++++++++++++++++++++++++++++++
>> include/cxl/cxl.h | 3 +++
>> 2 files changed, 42 insertions(+)
>>
>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
>> index c222e98ae736..006be88efaa5 100644
>> --- a/drivers/cxl/core/hdm.c
>> +++ b/drivers/cxl/core/hdm.c
>> @@ -686,6 +686,45 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
>> return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
>> }
>>
>> +static int find_committed_endpoint_decoder(struct device *dev, const void *data)
>> +{
>> + struct cxl_endpoint_decoder *cxled;
>> + struct cxl_port *port;
>> +
>> + if (!is_endpoint_decoder(dev))
>> + return 0;
>> +
>> + cxled = to_cxl_endpoint_decoder(dev);
>> + port = cxled_to_port(cxled);
>> +
>> + return cxled->cxld.id == port->hdm_end;
>> +}
>> +
>> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
>> + struct cxl_region **cxlr)
> kdoc header for this exported function?
Sure.
>
>> +{
>> + struct cxl_port *endpoint = cxlmd->endpoint;
>> + struct cxl_endpoint_decoder *cxled;
>> + struct device *cxled_dev;
>> +
>> + if (!endpoint)
>> + return NULL;
>> +
>> + guard(rwsem_read)(&cxl_rwsem.dpa);
>> + cxled_dev = device_find_child(&endpoint->dev, NULL,
>> + find_committed_endpoint_decoder);
>> +
>> + if (!cxled_dev)
>> + return NULL;
>> +
>> + cxled = to_cxl_endpoint_decoder(cxled_dev);
>> + *cxlr = cxled->cxld.region;
> Should SFC take a ref on the region device?
>
>> +
>> + put_device(cxled_dev);
> Maybe should let the caller release the reference? I think you will want to hold the reference by SFC until you no longer need the decoder?
I think this is not required as it is already referenced after the
memdev creation triggers the port allocation, hdm initialization and
region auto discovery.
Thank you!
>
> DJ
>
>> + return cxled;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(cxl_get_committed_decoder, "CXL");
>> +
>> static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
>> {
>> u16 eig;
>> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
>> index 10a9b8fa2f6b..2a61138e2a73 100644
>> --- a/include/cxl/cxl.h
>> +++ b/include/cxl/cxl.h
>> @@ -231,4 +231,7 @@ struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev,
>> int cxl_set_capacity(struct cxl_dev_state *cxlds, u64 capacity);
>> struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
>> const struct cxl_memdev_attach *attach);
>> +struct cxl_region;
>> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
>> + struct cxl_region **cxlr);
>> #endif /* __CXL_CXL_H__ */
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware
2026-03-24 17:38 ` Dave Jiang
@ 2026-03-24 22:02 ` Alejandro Lucero Palau
0 siblings, 0 replies; 29+ messages in thread
From: Alejandro Lucero Palau @ 2026-03-24 22:02 UTC (permalink / raw)
To: Dave Jiang, alejandro.lucero-palau, linux-cxl, netdev,
dan.j.williams, edward.cree, davem, kuba, pabeni, edumazet
Cc: Edward Cree
On 3/24/26 17:38, Dave Jiang wrote:
>
> On 3/23/26 4:31 AM, alejandro.lucero-palau@amd.com wrote:
>> From: Alejandro Lucero <alucerop@amd.com>
>>
>> Check if device HDM is already committed during firmware/BIOS
>> initialization.
>>
>> A CXL region should exist if so after memdev allocation/initialization.
>> Get HPA from region and map it.
>>
>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>> Acked-by: Edward Cree <ecree.xilinx@gmail.com>
>> ---
>> drivers/net/ethernet/sfc/efx_cxl.c | 24 ++++++++++++++++++++++++
>> 1 file changed, 24 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
>> index 22a7d1d95425..78f926300943 100644
>> --- a/drivers/net/ethernet/sfc/efx_cxl.c
>> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
>> @@ -19,6 +19,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> struct efx_nic *efx = &probe_data->efx;
>> struct pci_dev *pci_dev = efx->pci_dev;
>> struct efx_cxl *cxl;
>> + struct range range;
>> u16 dvsec;
>> int rc;
>>
>> @@ -82,6 +83,24 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>> return PTR_ERR(cxl->cxlmd);
>> }
>>
>> + cxl->cxled = cxl_get_committed_decoder(cxl->cxlmd, &cxl->efx_region);
>> + if (!cxl->cxled || !cxl->efx_region)
>> + return -ENODEV;
>> +
>> + rc = cxl_get_region_range(cxl->efx_region, &range);
>> + if (rc) {
>> + pci_err(pci_dev,
>> + "CXL getting regions params from a committed decoder failed");
>> + return rc;
>> + }
>> +
>> + cxl->ctpio_cxl = ioremap(range.start, range_len(&range));
>> + if (!cxl->ctpio_cxl) {
>> + pci_err(pci_dev, "CXL ioremap region (%pra) failed", &range);
>> + return -ENOMEM;
>> + }
>> +
>> +
>> probe_data->cxl = cxl;
>>
>> return 0;
>> @@ -89,6 +108,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
>>
>> void efx_cxl_exit(struct efx_probe_data *probe_data)
>> {
>> + if (!probe_data->cxl)
>> + return;
>> +
>> + iounmap(probe_data->cxl->ctpio_cxl);
>> + cxl_unregister_region(probe_data->cxl->efx_region);
> Would a device_put() on the region dev be sufficient here? Not sure if everything should be torn down if SFC didn't create the region to begin with and only retrieved it via cxl_get_commited_decoder()?
>
> DJ
I do not think so. The region will be around as current region creation
is "linked" to the root decoder. Only if the root decoder is removed
will the region release action be invoked. As I have mentioned when
replying Jonathan, maybe that should change.
Thank you
>
>> }
>>
>> MODULE_IMPORT_NS("CXL");
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 10/11] cxl: Avoid dax creation for accelerators
2026-03-23 11:31 ` [PATCH v24 10/11] cxl: Avoid dax creation for accelerators alejandro.lucero-palau
@ 2026-03-25 2:59 ` Alison Schofield
0 siblings, 0 replies; 29+ messages in thread
From: Alison Schofield @ 2026-03-25 2:59 UTC (permalink / raw)
To: alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Alejandro Lucero, Jonathan Cameron,
Davidlohr Bueso, Ben Cheatham
On Mon, Mar 23, 2026 at 11:31:16AM +0000, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>
> By definition a type2 cxl device will use the host managed memory for
> specific functionality, therefore it should not be available to other
> uses.
Hi Alejandro,
I'm wondering if we're skipping too much, or perhaps just needs
a clarifying comment?
Commit message says 'Avoid dax creation...', that's specific.
Commit log says 'should not be available to other uses', that's less specific
follow me ...
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Reviewed-by: Davidlohr Bueso <daves@stgolabs.net>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
> ---
> drivers/cxl/core/region.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 8bb53a095290..2f9bdb4f1f4f 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -4263,6 +4263,13 @@ static int cxl_region_probe(struct device *dev)
> if (rc)
> return rc;
>
> + /*
> + * HDM-D[B] (device-memory) regions have accelerator specific usage.
> + * Skip device-dax registration.
> + */
> + if (cxlr->type == CXL_DECODER_DEVMEM)
> + return 0;
> +
And above says 'Skip device-dax' specific again, and is indeed skipped.
This escape is not surgically placed at the point where dax is added.
We are skipping a few other things before dax registration actually
happens. Why skip memory notifiers, shutdown_notifiers, poison setup?
> /*
> * From this point on any path that changes the region's state away from
> * CXL_CONFIG_COMMIT is also responsible for releasing the driver.
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators
2026-03-24 21:36 ` Alejandro Lucero Palau
@ 2026-03-26 21:28 ` Cheatham, Benjamin
0 siblings, 0 replies; 29+ messages in thread
From: Cheatham, Benjamin @ 2026-03-26 21:28 UTC (permalink / raw)
To: Alejandro Lucero Palau, Jonathan Cameron, alejandro.lucero-palau
Cc: linux-cxl, netdev, dave.jiang, dan.j.williams, edward.cree, davem,
kuba, pabeni, edumazet, Gregory Price
On 3/24/2026 4:36 PM, Alejandro Lucero Palau wrote:
>
> On 3/24/26 16:50, Jonathan Cameron wrote:
>> On Mon, 23 Mar 2026 11:31:14 +0000
>> alejandro.lucero-palau@amd.com wrote:
>>
>>> From: Alejandro Lucero <alucerop@amd.com>
>>>
>>> Add cxl_unregister_region() to the accelerator driver API
>>> for a clean exit.
>>>
>>> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
>>> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
>> For this I'm seeing an outstanding question from Gregory on v23.
>
>
> Yes, I did not forget about it but I forgot to comment back.
>
>
> The kreview is obviously wrong but I think it points out to the missing invocation I need to add. I did not suffer those problems Gregory mentions, but I think that is due to how I configure my testing kernel. So, yes, I need to remove the release action from inside this function to avoid invoking ... this same function. That is another thing that puzzled me when I saw that review, and it implies I need to have different functions for accelerator driver specific invocation and for normal release action call. Or maybe just an extra param only removing the devm release action if invoked by accelerators. I think I will go with this last one. Any suggestion?
>
May be a dumb question, but what happens if you don't export this function and just rely on the devm action registered during creation in the core?
An extra parameter seems icky to me, but the alternative would be to push registering the release action to the endpoint driver (cxl_pci, sfc, etc.) which
is pretty rough as well.
I may just be missing something here, I haven't thought about this too much. I was going to look at the rest of the set tomorrow, I'll see if I can think
of something then.
Thanks,
Ben
>
> Thank you
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2026-03-26 21:28 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 11:31 [PATCH v24 00/11] Type2 device basic support alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 01/11] sfc: add cxl support alejandro.lucero-palau
2026-03-24 16:29 ` Jonathan Cameron
2026-03-24 21:05 ` Alejandro Lucero Palau
2026-03-23 11:31 ` [PATCH v24 02/11] cxl/sfc: Map cxl regs alejandro.lucero-palau
2026-03-24 16:33 ` Jonathan Cameron
2026-03-24 21:06 ` Alejandro Lucero Palau
2026-03-23 11:31 ` [PATCH v24 03/11] cxl/sfc: Initialize dpa without a mailbox alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 04/11] cxl: Prepare memdev creation for type2 alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 05/11] sfc: create type2 cxl memdev alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder alejandro.lucero-palau
2026-03-24 16:48 ` Jonathan Cameron
2026-03-24 21:20 ` Alejandro Lucero Palau
2026-03-24 17:32 ` Dave Jiang
2026-03-24 21:55 ` Alejandro Lucero Palau
2026-03-23 11:31 ` [PATCH v24 07/11] cxl: Add function for obtaining region range alejandro.lucero-palau
2026-03-23 11:31 ` [PATCH v24 08/11] cxl: Export function for unwinding cxl by accelerators alejandro.lucero-palau
2026-03-24 16:50 ` Jonathan Cameron
2026-03-24 21:36 ` Alejandro Lucero Palau
2026-03-26 21:28 ` Cheatham, Benjamin
2026-03-23 11:31 ` [PATCH v24 09/11] sfc: obtain decoder and region if committed by firmware alejandro.lucero-palau
2026-03-24 16:56 ` Jonathan Cameron
2026-03-24 21:43 ` Alejandro Lucero Palau
2026-03-24 17:38 ` Dave Jiang
2026-03-24 22:02 ` Alejandro Lucero Palau
2026-03-23 11:31 ` [PATCH v24 10/11] cxl: Avoid dax creation for accelerators alejandro.lucero-palau
2026-03-25 2:59 ` Alison Schofield
2026-03-23 11:31 ` [PATCH v24 11/11] sfc: support pio mapping based on cxl alejandro.lucero-palau
2026-03-23 22:18 ` Edward Cree
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox