* [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