Commit 7ec9db66 authored by Dave Jiang's avatar Dave Jiang
Browse files

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
parents 33bedb92 68f4a852
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+50 −4
Original line number Diff line number Diff line
@@ -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");
+20 −0
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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);