Merge branch 'for-6.19/cxl-elc-test' into cxl-for-next

Extended linear cache unit testing support
  - Standardize CXL auto region size
  - Add cxl_test CFMWS support for extended linear cache
  - Add support for acpi extended linear cache
This commit is contained in:
Dave Jiang 2025-11-17 11:05:47 -07:00
commit 7ec9db66cc
4 changed files with 74 additions and 4 deletions

View File

@ -10,6 +10,7 @@ ldflags-y += --wrap=cxl_rcd_component_reg_phys
ldflags-y += --wrap=cxl_endpoint_parse_cdat
ldflags-y += --wrap=cxl_dport_init_ras_reporting
ldflags-y += --wrap=devm_cxl_endpoint_decoders_setup
ldflags-y += --wrap=hmat_get_extended_linear_cache_size
DRIVERS := ../../../drivers
CXL_SRC := $(DRIVERS)/cxl

View File

@ -15,6 +15,7 @@
#include "mock.h"
static int interleave_arithmetic;
static bool extended_linear_cache;
#define FAKE_QTG_ID 42
@ -26,6 +27,9 @@ static int interleave_arithmetic;
#define NR_CXL_PORT_DECODERS 8
#define NR_BRIDGES (NR_CXL_HOST_BRIDGES + NR_CXL_SINGLE_HOST + NR_CXL_RCH)
#define MOCK_AUTO_REGION_SIZE_DEFAULT SZ_512M
static int mock_auto_region_size = MOCK_AUTO_REGION_SIZE_DEFAULT;
static struct platform_device *cxl_acpi;
static struct platform_device *cxl_host_bridge[NR_CXL_HOST_BRIDGES];
#define NR_MULTI_ROOT (NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS)
@ -426,6 +430,22 @@ static struct cxl_mock_res *alloc_mock_res(resource_size_t size, int align)
return res;
}
/* Only update CFMWS0 as this is used by the auto region. */
static void cfmws_elc_update(struct acpi_cedt_cfmws *window, int index)
{
if (!extended_linear_cache)
return;
if (index != 0)
return;
/*
* The window size should be 2x of the CXL region size where half is
* DRAM and half is CXL
*/
window->window_size = mock_auto_region_size * 2;
}
static int populate_cedt(void)
{
struct cxl_mock_res *res;
@ -450,6 +470,7 @@ static int populate_cedt(void)
for (i = cfmws_start; i <= cfmws_end; i++) {
struct acpi_cedt_cfmws *window = mock_cfmws[i];
cfmws_elc_update(window, i);
res = alloc_mock_res(window->window_size, SZ_256M);
if (!res)
return -ENOMEM;
@ -591,6 +612,25 @@ mock_acpi_evaluate_integer(acpi_handle handle, acpi_string pathname,
return AE_OK;
}
static int
mock_hmat_get_extended_linear_cache_size(struct resource *backing_res,
int nid, resource_size_t *cache_size)
{
struct acpi_cedt_cfmws *window = mock_cfmws[0];
struct resource cfmws0_res =
DEFINE_RES_MEM(window->base_hpa, window->window_size);
if (!extended_linear_cache ||
!resource_contains(&cfmws0_res, backing_res)) {
return hmat_get_extended_linear_cache_size(backing_res,
nid, cache_size);
}
*cache_size = mock_auto_region_size;
return 0;
}
static struct pci_bus mock_pci_bus[NR_BRIDGES];
static struct acpi_pci_root mock_pci_root[ARRAY_SIZE(mock_pci_bus)] = {
[0] = {
@ -738,7 +778,6 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld)
struct cxl_endpoint_decoder *cxled;
struct cxl_switch_decoder *cxlsd;
struct cxl_port *port, *iter;
const int size = SZ_512M;
struct cxl_memdev *cxlmd;
struct cxl_dport *dport;
struct device *dev;
@ -781,9 +820,11 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld)
}
base = window->base_hpa;
if (extended_linear_cache)
base += mock_auto_region_size;
cxld->hpa_range = (struct range) {
.start = base,
.end = base + size - 1,
.end = base + mock_auto_region_size - 1,
};
cxld->interleave_ways = 2;
@ -792,7 +833,8 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld)
cxld->flags = CXL_DECODER_F_ENABLE;
cxled->state = CXL_DECODER_STATE_AUTO;
port->commit_end = cxld->id;
devm_cxl_dpa_reserve(cxled, 0, size / cxld->interleave_ways, 0);
devm_cxl_dpa_reserve(cxled, 0,
mock_auto_region_size / cxld->interleave_ways, 0);
cxld->commit = mock_decoder_commit;
cxld->reset = mock_decoder_reset;
@ -841,7 +883,7 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld)
cxld->interleave_granularity = 4096;
cxld->hpa_range = (struct range) {
.start = base,
.end = base + size - 1,
.end = base + mock_auto_region_size - 1,
};
put_device(dev);
}
@ -1085,6 +1127,8 @@ static struct cxl_mock_ops cxl_mock_ops = {
.devm_cxl_endpoint_decoders_setup = mock_cxl_endpoint_decoders_setup,
.cxl_endpoint_parse_cdat = mock_cxl_endpoint_parse_cdat,
.devm_cxl_add_dport_by_dev = mock_cxl_add_dport_by_dev,
.hmat_get_extended_linear_cache_size =
mock_hmat_get_extended_linear_cache_size,
.list = LIST_HEAD_INIT(cxl_mock_ops.list),
};
@ -1574,6 +1618,8 @@ static __exit void cxl_test_exit(void)
module_param(interleave_arithmetic, int, 0444);
MODULE_PARM_DESC(interleave_arithmetic, "Modulo:0, XOR:1");
module_param(extended_linear_cache, bool, 0444);
MODULE_PARM_DESC(extended_linear_cache, "Enable extended linear cache support");
module_init(cxl_test_init);
module_exit(cxl_test_exit);
MODULE_LICENSE("GPL v2");

View File

@ -111,6 +111,26 @@ acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
}
EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
int __wrap_hmat_get_extended_linear_cache_size(struct resource *backing_res,
int nid,
resource_size_t *cache_size)
{
int index, rc;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops)
rc = ops->hmat_get_extended_linear_cache_size(backing_res, nid,
cache_size);
else
rc = hmat_get_extended_linear_cache_size(backing_res, nid,
cache_size);
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_GPL(__wrap_hmat_get_extended_linear_cache_size);
struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
{
int index;

View File

@ -24,6 +24,9 @@ struct cxl_mock_ops {
void (*cxl_endpoint_parse_cdat)(struct cxl_port *port);
struct cxl_dport *(*devm_cxl_add_dport_by_dev)(struct cxl_port *port,
struct device *dport_dev);
int (*hmat_get_extended_linear_cache_size)(struct resource *backing_res,
int nid,
resource_size_t *cache_size);
};
void register_cxl_mock_ops(struct cxl_mock_ops *ops);