* [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test
@ 2026-05-19 21:37 Dave Jiang
2026-05-19 21:37 ` [PATCH v2 1/6] cxl/test: Add test for module parameters Dave Jiang
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Dave Jiang @ 2026-05-19 21:37 UTC (permalink / raw)
To: linux-cxl; +Cc: djbw, dave, jic23, alison.schofield, vishal.l.verma
See individual patches for changes from previous version.
The series is based on v7.0-rc7 with Alejandro's type2 series v25 [1] and
with Dan's follow on series [2].
Series adds a 'type2_test' module parameter where it setup a mock type2
hierarchy with a mock type2 accelerator device directly under a root
port that has an auto region setup.
It also includes a CXL fix that was encountered when running tests with
the new code.
[
{
"memdevs":[
{
"memdev":"mem0",
"ram_size":536870912,
"ram_qos_class":42,
"host":"cxl_type2_accel.0",
"poison_injectable":false
}
]
},
{
"regions":[
{
"region":"region0",
"resource":70300293136384,
"size":536870912,
"type":"ram",
"interleave_ways":1,
"interleave_granularity":4096,
"decode_state":"commit"
}
]
}
]
"root decoders":[
{
"decoder":"decoder0.0",
"resource":70300293136384,
"size":1073741824,
"interleave_ways":1,
"accelmem_capable":true,
"qos_class":42,
"nr_targets":1
},
[1]: https://lore.kernel.org/linux-cxl/20260330143827.1278677-1-alejandro.lucero-palau@amd.com/T/#t
[2]: https://lore.kernel.org/linux-cxl/20260403210050.1058650-1-dan.j.williams@intel.com/T/#t
Dave Jiang (6):
cxl/test: Add test for module parameters
cxl/test: Add type2 support for mock CFMWS0
cxl/test: Refactor platform device enumerations
cxl/test: Add hierarchy enumeration support for type2 device
cxl/test: Fixup hdm init for auto region to support type2
cxl/test: Add cxl_test accelerator driver
tools/testing/cxl/test/Kbuild | 2 +
tools/testing/cxl/test/accel.c | 74 ++++
tools/testing/cxl/test/cxl.c | 629 ++++++++++++++++++++++++++-------
3 files changed, 571 insertions(+), 134 deletions(-)
create mode 100644 tools/testing/cxl/test/accel.c
base-commit: f47d7b8dbd872ba638dd9b2c25efae2d6cd14dca
--
2.54.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/6] cxl/test: Add test for module parameters
2026-05-19 21:37 [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test Dave Jiang
@ 2026-05-19 21:37 ` Dave Jiang
2026-05-19 21:37 ` [PATCH v2 2/6] cxl/test: Add type2 support for mock CFMWS0 Dave Jiang
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Dave Jiang @ 2026-05-19 21:37 UTC (permalink / raw)
To: linux-cxl; +Cc: djbw, dave, jic23, alison.schofield, vishal.l.verma
Add a test for module paraters during module init to make sure that
only one is activated.
Suggested-by: Alison Schofield <alison.schofield@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
tools/testing/cxl/test/cxl.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 48cae9dde2e4..e60cd0b2ac7b 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -1867,11 +1867,29 @@ static struct attribute *cxl_acpi_attrs[] = {
};
ATTRIBUTE_GROUPS(cxl_acpi);
+bool __init have_multiple_modparms(void)
+{
+ int count = 0;
+
+ if (interleave_arithmetic)
+ count++;
+ if (extended_linear_cache)
+ count++;
+ if (fail_autoassemble)
+ count++;
+
+ return count > 1;
+}
+
static __init int cxl_test_init(void)
{
int rc, i;
struct range mappable;
+ /* Enforce a single module param active at a time */
+ if (have_multiple_modparms())
+ return -EINVAL;
+
cxl_acpi_test();
cxl_core_test();
cxl_mem_test();
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/6] cxl/test: Add type2 support for mock CFMWS0
2026-05-19 21:37 [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test Dave Jiang
2026-05-19 21:37 ` [PATCH v2 1/6] cxl/test: Add test for module parameters Dave Jiang
@ 2026-05-19 21:37 ` Dave Jiang
2026-05-19 21:37 ` [PATCH v2 3/6] cxl/test: Refactor platform device enumerations Dave Jiang
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Dave Jiang @ 2026-05-19 21:37 UTC (permalink / raw)
To: linux-cxl; +Cc: djbw, dave, jic23, alison.schofield, vishal.l.verma
Add a module parameter 'type2_test' for triggering type2 test support
in cxl_test. Setup the CFMWS0 configuration to be type2 when 'type2_test'
is set.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
v2:
- Add exclusive module check
---
tools/testing/cxl/test/cxl.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index e60cd0b2ac7b..4893933d6789 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -17,6 +17,7 @@
static int interleave_arithmetic;
static bool extended_linear_cache;
static bool fail_autoassemble;
+static bool type2_test;
#define FAKE_QTG_ID 42
@@ -384,6 +385,19 @@ static struct {
},
};
+static struct acpi_cedt_cfmws type2_cfmws0 = {
+ .header = {
+ .type = ACPI_CEDT_TYPE_CFMWS,
+ .length = sizeof(mock_cedt.cfmws0),
+ },
+ .interleave_ways = 0,
+ .granularity = 4,
+ .restrictions = ACPI_CEDT_CFMWS_RESTRICT_DEVMEM |
+ ACPI_CEDT_CFMWS_RESTRICT_VOLATILE,
+ .qtg_id = FAKE_QTG_ID,
+ .window_size = SZ_256M * 4,
+};
+
struct acpi_cedt_cfmws *mock_cfmws[] = {
[0] = &mock_cedt.cfmws0.cfmws,
[1] = &mock_cedt.cfmws1.cfmws,
@@ -472,6 +486,11 @@ static void cfmws_elc_update(struct acpi_cedt_cfmws *window, int index)
window->window_size = mock_auto_region_size * 2;
}
+static void update_type2_cfmws(void)
+{
+ memcpy(&mock_cedt.cfmws0.cfmws, &type2_cfmws0, sizeof(type2_cfmws0));
+}
+
static int populate_cedt(void)
{
struct cxl_mock_res *res;
@@ -493,10 +512,14 @@ static int populate_cedt(void)
chbs->length = size;
}
+ if (type2_test)
+ update_type2_cfmws();
+
for (i = cfmws_start; i <= cfmws_end; i++) {
struct acpi_cedt_cfmws *window = mock_cfmws[i];
- cfmws_elc_update(window, i);
+ if (i == 0 && !type2_test)
+ cfmws_elc_update(window, i);
res = alloc_mock_res(window->window_size, SZ_256M);
if (!res)
return -ENOMEM;
@@ -1877,6 +1900,8 @@ bool __init have_multiple_modparms(void)
count++;
if (fail_autoassemble)
count++;
+ if (type2_test)
+ count++;
return count > 1;
}
@@ -2113,6 +2138,8 @@ module_param(extended_linear_cache, bool, 0444);
MODULE_PARM_DESC(extended_linear_cache, "Enable extended linear cache support");
module_param(fail_autoassemble, bool, 0444);
MODULE_PARM_DESC(fail_autoassemble, "Simulate missing member of an auto-region");
+module_param(type2_test, bool, 0444);
+MODULE_PARM_DESC(type2_test, "Enable type 2 support testing");
module_init(cxl_test_init);
module_exit(cxl_test_exit);
MODULE_LICENSE("GPL v2");
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/6] cxl/test: Refactor platform device enumerations
2026-05-19 21:37 [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test Dave Jiang
2026-05-19 21:37 ` [PATCH v2 1/6] cxl/test: Add test for module parameters Dave Jiang
2026-05-19 21:37 ` [PATCH v2 2/6] cxl/test: Add type2 support for mock CFMWS0 Dave Jiang
@ 2026-05-19 21:37 ` Dave Jiang
2026-05-19 21:37 ` [PATCH v2 4/6] cxl/test: Add hierarchy enumeration support for type2 device Dave Jiang
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Dave Jiang @ 2026-05-19 21:37 UTC (permalink / raw)
To: linux-cxl; +Cc: djbw, dave, jic23, alison.schofield, vishal.l.verma
Split all the host bridges, rootports, upstream and downstream ports
enumerations to separate helper functions. This should make adding
type2 hierarchy easier later on.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
v2:
- Swap cxl_usps_remove() and cxl_dsps_remove(). (Alison)
---
tools/testing/cxl/test/cxl.c | 328 +++++++++++++++++++++++------------
1 file changed, 218 insertions(+), 110 deletions(-)
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 4893933d6789..e2b5ec8e6982 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -1906,10 +1906,208 @@ bool __init have_multiple_modparms(void)
return count > 1;
}
+static void host_bridges_remove(void)
+{
+ int i;
+
+ for (i = ARRAY_SIZE(cxl_host_bridge) - 1; i >= 0; i--) {
+ struct platform_device *pdev = cxl_host_bridge[i];
+
+ if (!pdev)
+ break;
+
+ sysfs_remove_link(&pdev->dev.kobj, "physical_node");
+ platform_device_unregister(cxl_host_bridge[i]);
+ }
+}
+
+static int host_bridges_populate(void)
+{
+ int rc = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(cxl_host_bridge); i++) {
+ struct acpi_device *adev = &host_bridge[i];
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("cxl_host_bridge", i);
+ if (!pdev)
+ goto err_bridge;
+
+ mock_companion(adev, &pdev->dev);
+ rc = platform_device_add(pdev);
+ if (rc) {
+ platform_device_put(pdev);
+ goto err_bridge;
+ }
+
+ cxl_host_bridge[i] = pdev;
+ mock_pci_bus[i].bridge = &pdev->dev;
+ rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+ "physical_node");
+ if (rc)
+ goto err_bridge;
+ }
+
+ return 0;
+
+err_bridge:
+ host_bridges_remove();
+ return rc;
+}
+
+static void cxl_rootports_remove(void)
+{
+ for (int i = ARRAY_SIZE(cxl_root_port) - 1; i >= 0; i--) {
+ struct platform_device *pdev = cxl_root_port[i];
+
+ if (!pdev)
+ break;
+
+ platform_device_unregister(pdev);
+ }
+}
+
+static int cxl_rootports_populate(void)
+{
+ int rc = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(cxl_root_port); i++) {
+ struct platform_device *bridge =
+ cxl_host_bridge[i % ARRAY_SIZE(cxl_host_bridge)];
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("cxl_root_port", i);
+ if (!pdev)
+ goto err_port;
+
+ pdev->dev.parent = &bridge->dev;
+
+ rc = platform_device_add(pdev);
+ if (rc) {
+ platform_device_put(pdev);
+ goto err_port;
+ }
+ cxl_root_port[i] = pdev;
+ }
+
+ return 0;
+
+err_port:
+ cxl_rootports_remove();
+ return rc;
+}
+
+static void cxl_usps_remove(void)
+{
+ for (int i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--) {
+ struct platform_device *pdev = cxl_switch_uport[i];
+
+ if (!pdev)
+ break;
+
+ platform_device_unregister(cxl_switch_uport[i]);
+ }
+}
+
+static int cxl_usps_populate(void)
+{
+ int rc = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(cxl_switch_uport); i++) {
+ struct platform_device *root_port = cxl_root_port[i];
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("cxl_switch_uport", i);
+ if (!pdev)
+ goto err_uport;
+
+ pdev->dev.parent = &root_port->dev;
+
+ rc = platform_device_add(pdev);
+ if (rc) {
+ platform_device_put(pdev);
+ goto err_uport;
+ }
+ cxl_switch_uport[i] = pdev;
+ }
+
+ return 0;
+
+err_uport:
+ cxl_usps_remove();
+ return rc;
+}
+
+static void cxl_dsps_remove(void)
+{
+ for (int i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--) {
+ struct platform_device *pdev = cxl_switch_dport[i];
+
+ if (!pdev)
+ break;
+
+ platform_device_unregister(cxl_switch_dport[i]);
+ }
+}
+
+
+static int cxl_dsps_populate(void)
+{
+ int rc = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
+ struct platform_device *uport =
+ cxl_switch_uport[i % ARRAY_SIZE(cxl_switch_uport)];
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("cxl_switch_dport", i);
+ if (!pdev)
+ goto err_dport;
+ pdev->dev.parent = &uport->dev;
+
+ rc = platform_device_add(pdev);
+ if (rc) {
+ platform_device_put(pdev);
+ goto err_dport;
+ }
+ cxl_switch_dport[i] = pdev;
+ }
+
+ return 0;
+
+err_dport:
+ cxl_dsps_remove();
+ return rc;
+}
+
+static void cxl_switches_remove(void)
+{
+ cxl_dsps_remove();
+ cxl_usps_remove();
+}
+
+static int cxl_switches_populate(void)
+{
+ int rc;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
+ rc = cxl_usps_populate();
+ if (rc)
+ return rc;
+
+ rc = cxl_dsps_populate();
+ if (rc) {
+ cxl_usps_remove();
+ return rc;
+ }
+
+ return 0;
+}
+
static __init int cxl_test_init(void)
{
- int rc, i;
struct range mappable;
+ int rc;
/* Enforce a single module param active at a time */
if (have_multiple_modparms())
@@ -1949,86 +2147,21 @@ static __init int cxl_test_init(void)
if (rc)
goto err_populate;
- for (i = 0; i < ARRAY_SIZE(cxl_host_bridge); i++) {
- struct acpi_device *adev = &host_bridge[i];
- struct platform_device *pdev;
+ rc = host_bridges_populate();
+ if (rc)
+ goto err_populate;
- pdev = platform_device_alloc("cxl_host_bridge", i);
- if (!pdev)
- goto err_bridge;
+ rc = cxl_rootports_populate();
+ if (rc)
+ goto err_host_bridges;
- mock_companion(adev, &pdev->dev);
- rc = platform_device_add(pdev);
- if (rc) {
- platform_device_put(pdev);
- goto err_bridge;
- }
-
- cxl_host_bridge[i] = pdev;
- mock_pci_bus[i].bridge = &pdev->dev;
- rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
- "physical_node");
- if (rc)
- goto err_bridge;
- }
-
- for (i = 0; i < ARRAY_SIZE(cxl_root_port); i++) {
- struct platform_device *bridge =
- cxl_host_bridge[i % ARRAY_SIZE(cxl_host_bridge)];
- struct platform_device *pdev;
-
- pdev = platform_device_alloc("cxl_root_port", i);
- if (!pdev)
- goto err_port;
- pdev->dev.parent = &bridge->dev;
-
- rc = platform_device_add(pdev);
- if (rc) {
- platform_device_put(pdev);
- goto err_port;
- }
- cxl_root_port[i] = pdev;
- }
-
- BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
- for (i = 0; i < ARRAY_SIZE(cxl_switch_uport); i++) {
- struct platform_device *root_port = cxl_root_port[i];
- struct platform_device *pdev;
-
- pdev = platform_device_alloc("cxl_switch_uport", i);
- if (!pdev)
- goto err_uport;
- pdev->dev.parent = &root_port->dev;
-
- rc = platform_device_add(pdev);
- if (rc) {
- platform_device_put(pdev);
- goto err_uport;
- }
- cxl_switch_uport[i] = pdev;
- }
-
- for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
- struct platform_device *uport =
- cxl_switch_uport[i % ARRAY_SIZE(cxl_switch_uport)];
- struct platform_device *pdev;
-
- pdev = platform_device_alloc("cxl_switch_dport", i);
- if (!pdev)
- goto err_dport;
- pdev->dev.parent = &uport->dev;
-
- rc = platform_device_add(pdev);
- if (rc) {
- platform_device_put(pdev);
- goto err_dport;
- }
- cxl_switch_dport[i] = pdev;
- }
+ rc = cxl_switches_populate();
+ if (rc)
+ goto err_root_ports;
rc = cxl_single_topo_init();
if (rc)
- goto err_dport;
+ goto err_switches;
rc = cxl_rch_topo_init();
if (rc)
@@ -2064,24 +2197,12 @@ static __init int cxl_test_init(void)
cxl_rch_topo_exit();
err_single:
cxl_single_topo_exit();
-err_dport:
- for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
- platform_device_unregister(cxl_switch_dport[i]);
-err_uport:
- for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
- platform_device_unregister(cxl_switch_uport[i]);
-err_port:
- for (i = ARRAY_SIZE(cxl_root_port) - 1; i >= 0; i--)
- platform_device_unregister(cxl_root_port[i]);
-err_bridge:
- for (i = ARRAY_SIZE(cxl_host_bridge) - 1; i >= 0; i--) {
- struct platform_device *pdev = cxl_host_bridge[i];
-
- if (!pdev)
- continue;
- sysfs_remove_link(&pdev->dev.kobj, "physical_node");
- platform_device_unregister(cxl_host_bridge[i]);
- }
+err_switches:
+ cxl_switches_remove();
+err_root_ports:
+ cxl_rootports_remove();
+err_host_bridges:
+ host_bridges_remove();
err_populate:
depopulate_all_mock_resources();
err_gen_pool_add:
@@ -2104,27 +2225,14 @@ static void free_decoder_registry(void)
static __exit void cxl_test_exit(void)
{
- int i;
-
hmem_test_exit();
cxl_mem_exit();
platform_device_unregister(cxl_acpi);
cxl_rch_topo_exit();
cxl_single_topo_exit();
- for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
- platform_device_unregister(cxl_switch_dport[i]);
- for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
- platform_device_unregister(cxl_switch_uport[i]);
- for (i = ARRAY_SIZE(cxl_root_port) - 1; i >= 0; i--)
- platform_device_unregister(cxl_root_port[i]);
- for (i = ARRAY_SIZE(cxl_host_bridge) - 1; i >= 0; i--) {
- struct platform_device *pdev = cxl_host_bridge[i];
-
- if (!pdev)
- continue;
- sysfs_remove_link(&pdev->dev.kobj, "physical_node");
- platform_device_unregister(cxl_host_bridge[i]);
- }
+ cxl_switches_remove();
+ cxl_rootports_remove();
+ host_bridges_remove();
depopulate_all_mock_resources();
gen_pool_destroy(cxl_mock_pool);
unregister_cxl_mock_ops(&cxl_mock_ops);
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 4/6] cxl/test: Add hierarchy enumeration support for type2 device
2026-05-19 21:37 [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test Dave Jiang
` (2 preceding siblings ...)
2026-05-19 21:37 ` [PATCH v2 3/6] cxl/test: Refactor platform device enumerations Dave Jiang
@ 2026-05-19 21:37 ` Dave Jiang
2026-05-19 21:37 ` [PATCH v2 5/6] cxl/test: Fixup hdm init for auto region to support type2 Dave Jiang
2026-05-19 21:37 ` [PATCH v2 6/6] cxl/test: Add cxl_test accelerator driver Dave Jiang
5 siblings, 0 replies; 7+ messages in thread
From: Dave Jiang @ 2026-05-19 21:37 UTC (permalink / raw)
To: linux-cxl; +Cc: djbw, dave, jic23, alison.schofield, vishal.l.verma
Add enumeration of type2 device hierarchy in cxl-test. The type2 device
is setup to be directly attached to a root port instead of rp -> switch
-> device that type3 hierarchy is setup..
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
v2:
- Set type2 memdev to 1. (Alison)
- Refactor topo init to device type specific. (Alison)
---
tools/testing/cxl/test/cxl.c | 217 ++++++++++++++++++++++++++++-------
1 file changed, 177 insertions(+), 40 deletions(-)
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index e2b5ec8e6982..2a39b2575f06 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -28,6 +28,7 @@ static bool type2_test;
#define NR_CXL_SWITCH_PORTS 2
#define NR_CXL_PORT_DECODERS 8
#define NR_BRIDGES (NR_CXL_HOST_BRIDGES + NR_CXL_SINGLE_HOST + NR_CXL_RCH)
+#define NR_CXL_TYPE2_ACCEL 1
#define MOCK_AUTO_REGION_SIZE_DEFAULT SZ_512M
static int mock_auto_region_size = MOCK_AUTO_REGION_SIZE_DEFAULT;
@@ -1778,19 +1779,90 @@ static void cxl_single_topo_exit(void)
}
}
+static void cxl_type3_mem_exit(void)
+{
+ struct platform_device *pdev;
+ int i;
+
+ for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--) {
+ pdev = cxl_rcd[i];
+ if (!pdev)
+ break;
+ platform_device_unregister(cxl_rcd[i]);
+ }
+
+ for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--) {
+ pdev = cxl_mem_single[i];
+ if (!pdev)
+ break;
+ platform_device_unregister(cxl_mem_single[i]);
+ }
+
+ for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--) {
+ pdev = cxl_mem[i];
+ if (!pdev)
+ break;
+ platform_device_unregister(pdev);
+ }
+}
+
+static void cxl_type2_mem_exit(void)
+{
+ for (int i = NR_CXL_TYPE2_ACCEL - 1; i >= 0; i--) {
+ struct platform_device *pdev = cxl_mem[i];
+
+ if (!pdev)
+ break;
+ platform_device_unregister(pdev);
+ }
+}
+
static void cxl_mem_exit(void)
{
- int i;
+ if (type2_test) {
+ cxl_type2_mem_exit();
+ return;
+ }
- for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
- platform_device_unregister(cxl_rcd[i]);
- for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
- platform_device_unregister(cxl_mem_single[i]);
- for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
+ cxl_type3_mem_exit();
+}
+
+static int cxl_type2_mem_init(void)
+{
+ int i, rc;
+
+ for (i = 0; i < NR_CXL_TYPE2_ACCEL; i++) {
+ struct platform_device *dport = cxl_root_port[i];
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("cxl_type2_accel", i);
+ if (!pdev)
+ goto err_mem;
+ pdev->dev.parent = &dport->dev;
+ set_dev_node(&pdev->dev, i % 2);
+
+ rc = platform_device_add(pdev);
+ if (rc) {
+ platform_device_put(pdev);
+ goto err_mem;
+ }
+ cxl_mem[i] = pdev;
+ }
+
+ return 0;
+
+err_mem:
+ for (i = NR_CXL_TYPE2_ACCEL - 1; i >= 0; i--) {
+ struct platform_device *pdev = cxl_mem[i];
+
+ if (!pdev)
+ break;
platform_device_unregister(cxl_mem[i]);
+ }
+ return rc;
}
-static int cxl_mem_init(void)
+static int cxl_type3_mem_init(void)
{
int i, rc;
@@ -1863,6 +1935,13 @@ static int cxl_mem_init(void)
return rc;
}
+static int cxl_mem_init(void)
+{
+ if (type2_test)
+ return cxl_type2_mem_init();
+ return cxl_type3_mem_init();
+}
+
static ssize_t
decoder_reset_preserve_registry_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -2104,6 +2183,92 @@ static int cxl_switches_populate(void)
return 0;
}
+static void cxl_type2_topo_exit(void)
+{
+ host_bridges_remove();
+ cxl_rootports_remove();
+}
+
+static int cxl_type2_topo_init(void)
+{
+ int rc;
+
+ rc = host_bridges_populate();
+ if (rc)
+ return rc;
+
+ rc = cxl_rootports_populate();
+ if (rc) {
+ host_bridges_remove();
+ return rc;
+ }
+
+ return 0;
+}
+
+static void cxl_type3_topo_exit(void)
+{
+ host_bridges_remove();
+ cxl_rootports_remove();
+ cxl_switches_remove();
+ cxl_single_topo_exit();
+ cxl_rch_topo_exit();
+}
+
+static int cxl_type3_topo_init(void)
+{
+ int rc;
+
+ rc = host_bridges_populate();
+ if (rc)
+ return rc;
+
+ rc = cxl_rootports_populate();
+ if (rc)
+ goto err_host_bridges;
+
+ rc = cxl_switches_populate();
+ if (rc)
+ goto err_root_ports;
+
+ rc = cxl_single_topo_init();
+ if (rc)
+ goto err_switches;
+
+ rc = cxl_rch_topo_init();
+ if (rc)
+ goto err_single;
+
+ return 0;
+
+err_single:
+ cxl_single_topo_exit();
+err_switches:
+ cxl_switches_remove();
+err_root_ports:
+ cxl_rootports_remove();
+err_host_bridges:
+ host_bridges_remove();
+ return rc;
+}
+
+static void cxl_topo_exit(void)
+{
+ if (type2_test) {
+ cxl_type2_topo_exit();
+ return;
+ }
+
+ cxl_type3_topo_exit();
+}
+
+static int cxl_topo_init(void)
+{
+ if (type2_test)
+ return cxl_type2_topo_init();
+ return cxl_type3_topo_init();
+}
+
static __init int cxl_test_init(void)
{
struct range mappable;
@@ -2147,29 +2312,13 @@ static __init int cxl_test_init(void)
if (rc)
goto err_populate;
- rc = host_bridges_populate();
+ rc = cxl_topo_init();
if (rc)
goto err_populate;
- rc = cxl_rootports_populate();
- if (rc)
- goto err_host_bridges;
-
- rc = cxl_switches_populate();
- if (rc)
- goto err_root_ports;
-
- rc = cxl_single_topo_init();
- if (rc)
- goto err_switches;
-
- rc = cxl_rch_topo_init();
- if (rc)
- goto err_single;
-
cxl_acpi = platform_device_alloc("cxl_acpi", 0);
if (!cxl_acpi)
- goto err_rch;
+ goto err_topo;
mock_companion(&acpi0017_mock, &cxl_acpi->dev);
acpi0017_mock.dev.bus = &platform_bus_type;
@@ -2193,16 +2342,8 @@ static __init int cxl_test_init(void)
cxl_mem_exit();
err_root:
platform_device_put(cxl_acpi);
-err_rch:
- cxl_rch_topo_exit();
-err_single:
- cxl_single_topo_exit();
-err_switches:
- cxl_switches_remove();
-err_root_ports:
- cxl_rootports_remove();
-err_host_bridges:
- host_bridges_remove();
+err_topo:
+ cxl_topo_exit();
err_populate:
depopulate_all_mock_resources();
err_gen_pool_add:
@@ -2228,11 +2369,7 @@ static __exit void cxl_test_exit(void)
hmem_test_exit();
cxl_mem_exit();
platform_device_unregister(cxl_acpi);
- cxl_rch_topo_exit();
- cxl_single_topo_exit();
- cxl_switches_remove();
- cxl_rootports_remove();
- host_bridges_remove();
+ cxl_topo_exit();
depopulate_all_mock_resources();
gen_pool_destroy(cxl_mock_pool);
unregister_cxl_mock_ops(&cxl_mock_ops);
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 5/6] cxl/test: Fixup hdm init for auto region to support type2
2026-05-19 21:37 [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test Dave Jiang
` (3 preceding siblings ...)
2026-05-19 21:37 ` [PATCH v2 4/6] cxl/test: Add hierarchy enumeration support for type2 device Dave Jiang
@ 2026-05-19 21:37 ` Dave Jiang
2026-05-19 21:37 ` [PATCH v2 6/6] cxl/test: Add cxl_test accelerator driver Dave Jiang
5 siblings, 0 replies; 7+ messages in thread
From: Dave Jiang @ 2026-05-19 21:37 UTC (permalink / raw)
To: linux-cxl; +Cc: djbw, dave, jic23, alison.schofield, vishal.l.verma
Add support to setup initialization of decoders in order to support
type2 auto region.
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
tools/testing/cxl/test/cxl.c | 73 +++++++++++++++++++++++++++++++++++-
1 file changed, 72 insertions(+), 1 deletion(-)
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 2a39b2575f06..042f057e42eb 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -1081,6 +1081,7 @@ enum cxld_init_type {
MOCK_DECODER_INIT_DEFAULT,
MOCK_DECODER_INIT_SAVED,
MOCK_DECODER_INIT_TYPE3_AUTO,
+ MOCK_DECODER_INIT_TYPE2_AUTO,
};
static enum cxld_init_type get_decoder_init_type(struct cxl_decoder *cxld,
@@ -1109,7 +1110,8 @@ static enum cxld_init_type get_decoder_init_type(struct cxl_decoder *cxld,
pdev->id > 4 || cxld->id > 0)
return MOCK_DECODER_INIT_DEFAULT;
- return MOCK_DECODER_INIT_TYPE3_AUTO;
+ return type2_test ? MOCK_DECODER_INIT_TYPE2_AUTO :
+ MOCK_DECODER_INIT_TYPE3_AUTO;
}
static bool mock_decoder_handle_saved(struct cxl_decoder *cxld, struct cxl_test_decoder *td)
@@ -1128,6 +1130,70 @@ static bool mock_decoder_handle_saved(struct cxl_decoder *cxld, struct cxl_test_
return false;
}
+static void mock_init_hdm_type2_cxled(struct cxl_endpoint_decoder *cxled,
+ struct cxl_port *port,
+ struct platform_device *pdev)
+{
+ struct acpi_cedt_cfmws *window = mock_cfmws[0];
+ struct cxl_decoder *cxld = &cxled->cxld;
+ struct cxl_switch_decoder *cxlsd;
+ struct cxl_dport *dport;
+ struct cxl_port *root_port;
+ struct device *dev;
+ u64 base;
+
+ base = window->base_hpa;
+ cxld->hpa_range = (struct range) {
+ .start = base,
+ .end = base + mock_auto_region_size - 1,
+ };
+
+ cxld->interleave_ways = 1;
+ eig_to_granularity(window->granularity, &cxld->interleave_granularity);
+ cxld->target_type = CXL_DECODER_DEVMEM;
+ cxld->flags = CXL_DECODER_F_ENABLE;
+ cxled->state = CXL_DECODER_STATE_AUTO;
+ port->commit_end = cxld->id;
+ devm_cxl_dpa_reserve(cxled, 0,
+ mock_auto_region_size / cxld->interleave_ways, 0);
+ cxld->commit = mock_decoder_commit;
+ cxld->reset = mock_decoder_reset;
+
+ WARN_ON_ONCE(!cxld_registry_new(cxld));
+ /*
+ * Now that endpoint decoder is set up, walk up the hierarchy
+ * and setup the root port decoder targeting @cxlmd.
+ */
+ dport = port->parent_dport;
+ root_port = dport->port;
+ dev = device_find_child(&root_port->dev, NULL, first_decoder);
+ /*
+ * Ancestor ports are guaranteed to be enumerated before
+ * @port, and all ports have at least one decoder.
+ */
+ if (WARN_ON(!dev))
+ return;
+
+ cxlsd = to_cxl_switch_decoder(dev);
+ cxlsd->target[0] = dport;
+ cxlsd->cxld.target_map[0] = dport->port_id;
+ cxld = &cxlsd->cxld;
+ cxld->target_type = CXL_DECODER_DEVMEM;
+ cxld->flags = CXL_DECODER_F_ENABLE;
+ root_port->commit_end = 0;
+ cxld->interleave_ways = 1;
+ cxld->interleave_granularity = 4096;
+ cxld->hpa_range = (struct range) {
+ .start = base,
+ .end = base + mock_auto_region_size - 1,
+ };
+ cxld->commit = mock_decoder_commit;
+ cxld->reset = mock_decoder_reset;
+
+ cxld_registry_update(cxld);
+ put_device(dev);
+}
+
static void mock_init_hdm_type3_cxled(struct cxl_endpoint_decoder *cxled,
struct cxl_port *port,
struct platform_device *pdev,
@@ -1285,6 +1351,11 @@ static bool mock_init_hdm_decoder(struct cxl_decoder *cxld)
case MOCK_DECODER_INIT_TYPE3_AUTO:
mock_init_hdm_type3_cxled(cxled, port, pdev, hb0);
return false;
+ case MOCK_DECODER_INIT_TYPE2_AUTO:
+ mock_init_hdm_type2_cxled(cxled, port, pdev);
+ return false;
+ default:
+ return false;
}
return false;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 6/6] cxl/test: Add cxl_test accelerator driver
2026-05-19 21:37 [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test Dave Jiang
` (4 preceding siblings ...)
2026-05-19 21:37 ` [PATCH v2 5/6] cxl/test: Fixup hdm init for auto region to support type2 Dave Jiang
@ 2026-05-19 21:37 ` Dave Jiang
5 siblings, 0 replies; 7+ messages in thread
From: Dave Jiang @ 2026-05-19 21:37 UTC (permalink / raw)
To: linux-cxl; +Cc: djbw, dave, jic23, alison.schofield, vishal.l.verma
Add a type2 accelerator mock driver for the platform device that
simulates a CXL type2 device. The driver exercises the same
minimal API calls that a real CXL type2 driver would utilize.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
v2:
- Remove unused headers. (Alison)
- devm_cxl_dev_state_create() err return -ENOMEM. (Alison)
---
tools/testing/cxl/test/Kbuild | 2 +
tools/testing/cxl/test/accel.c | 74 ++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+)
create mode 100644 tools/testing/cxl/test/accel.c
diff --git a/tools/testing/cxl/test/Kbuild b/tools/testing/cxl/test/Kbuild
index c168e3c998a7..9a24ddc28488 100644
--- a/tools/testing/cxl/test/Kbuild
+++ b/tools/testing/cxl/test/Kbuild
@@ -5,10 +5,12 @@ obj-m += cxl_test.o
obj-m += cxl_mock.o
obj-m += cxl_mock_mem.o
obj-m += cxl_translate.o
+obj-m += cxl_mock_accel.o
cxl_test-y := cxl.o
cxl_test-y += hmem_test.o
cxl_mock-y := mock.o
cxl_mock_mem-y := mem.o
+cxl_mock_accel-y := accel.o
KBUILD_CFLAGS := $(filter-out -Wmissing-prototypes -Wmissing-declarations, $(KBUILD_CFLAGS))
diff --git a/tools/testing/cxl/test/accel.c b/tools/testing/cxl/test/accel.c
new file mode 100644
index 000000000000..f427383670f6
--- /dev/null
+++ b/tools/testing/cxl/test/accel.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2026 Intel Corporation. All rights reserved.
+
+#include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/sizes.h>
+#include <cxl/mailbox.h>
+#include <cxlmem.h>
+
+struct mock_cxl_accel {
+ struct cxl_dev_state cxlds;
+ struct cxl_memdev *cxlmd;
+};
+
+static int cxl_mock_accel_probe(struct platform_device *pdev)
+{
+ struct cxl_attach_region *attach;
+ struct mock_cxl_accel *cxl_accel;
+ struct device *dev = &pdev->dev;
+ struct cxl_dev_state *cxlds;
+ struct cxl_memdev *cxlmd;
+ int rc;
+
+ attach = devm_kzalloc(dev, sizeof(attach), GFP_KERNEL);
+ if (!attach)
+ return -ENOMEM;
+
+ *attach = (struct cxl_attach_region) {
+ .attach = {
+ .probe = cxl_memdev_attach_region,
+ }
+ };
+
+ cxl_accel = devm_cxl_dev_state_create(&pdev->dev, CXL_DEVTYPE_DEVMEM,
+ pdev->dev.id + 1, 0,
+ struct mock_cxl_accel, cxlds,
+ false);
+ if (!cxl_accel)
+ return -ENOMEM;
+
+ cxlds = &cxl_accel->cxlds;
+ cxlds->media_ready = true;
+ rc = cxl_set_capacity(cxlds, SZ_512M);
+ if (rc)
+ return rc;
+
+ cxlmd = devm_cxl_add_memdev(cxlds, &attach->attach);
+ if (IS_ERR(cxlmd))
+ return PTR_ERR(cxlmd);
+ cxl_accel->cxlmd = cxlmd;
+
+ return 0;
+}
+
+static const struct platform_device_id cxl_mock_accel_ids[] = {
+ { .name = "cxl_type2_accel", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, cxl_mock_accel_ids);
+
+static struct platform_driver cxl_mock_accel_driver = {
+ .probe = cxl_mock_accel_probe,
+ .id_table = cxl_mock_accel_ids,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+};
+
+module_platform_driver(cxl_mock_accel_driver);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("cxl_test: accelerator device mock module");
+MODULE_IMPORT_NS("CXL");
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-19 21:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-19 21:37 [PATCH v2 0/6] cxl: Add CXL type2 accelerator support for cxl_test Dave Jiang
2026-05-19 21:37 ` [PATCH v2 1/6] cxl/test: Add test for module parameters Dave Jiang
2026-05-19 21:37 ` [PATCH v2 2/6] cxl/test: Add type2 support for mock CFMWS0 Dave Jiang
2026-05-19 21:37 ` [PATCH v2 3/6] cxl/test: Refactor platform device enumerations Dave Jiang
2026-05-19 21:37 ` [PATCH v2 4/6] cxl/test: Add hierarchy enumeration support for type2 device Dave Jiang
2026-05-19 21:37 ` [PATCH v2 5/6] cxl/test: Fixup hdm init for auto region to support type2 Dave Jiang
2026-05-19 21:37 ` [PATCH v2 6/6] cxl/test: Add cxl_test accelerator driver Dave Jiang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.