Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
# SPDX-License-Identifier: GPL-2.0
ldflags-y += --wrap=acpi_table_parse_cedt
ldflags-y += --wrap=is_acpi_device_node
ldflags-y += --wrap=acpi_evaluate_integer
ldflags-y += --wrap=acpi_pci_find_root
ldflags-y += --wrap=nvdimm_bus_register
ldflags-y += --wrap=cxl_await_media_ready
ldflags-y += --wrap=devm_cxl_add_rch_dport
ldflags-y += --wrap=cxl_endpoint_parse_cdat
ldflags-y += --wrap=devm_cxl_endpoint_decoders_setup
ldflags-y += --wrap=hmat_get_extended_linear_cache_size
ldflags-y += --wrap=devm_cxl_add_dport_by_dev
ldflags-y += --wrap=devm_cxl_switch_port_decoders_setup
ldflags-y += --wrap=walk_hmem_resources
ldflags-y += --wrap=region_intersects
ldflags-y += --wrap=region_intersects_soft_reserve
DRIVERS := ../../../drivers
DAX_HMEM_SRC := $(DRIVERS)/dax/hmem
CXL_SRC := $(DRIVERS)/cxl
CXL_CORE_SRC := $(DRIVERS)/cxl/core
ccflags-y := -I$(srctree)/drivers/cxl/
ccflags-y += -D__mock=__weak
ccflags-y += -DCXL_TEST_ENABLE=1
ccflags-y += -DTRACE_INCLUDE_PATH=$(CXL_CORE_SRC) -I$(srctree)/drivers/cxl/core/
obj-m += cxl_acpi.o
cxl_acpi-y := $(CXL_SRC)/acpi.o
cxl_acpi-y += mock_acpi.o
cxl_acpi-y += config_check.o
cxl_acpi-y += cxl_acpi_test.o
obj-m += cxl_pmem.o
cxl_pmem-y := $(CXL_SRC)/pmem.o
cxl_pmem-y += $(CXL_SRC)/security.o
cxl_pmem-y += config_check.o
cxl_pmem-y += cxl_pmem_test.o
obj-m += cxl_port.o
cxl_port-y := $(CXL_SRC)/port.o
cxl_port-y += config_check.o
cxl_port-y += cxl_port_test.o
obj-m += cxl_mem.o
cxl_mem-y := $(CXL_SRC)/mem.o
cxl_mem-y += config_check.o
cxl_mem-y += cxl_mem_test.o
obj-m += cxl_core.o
cxl_core-y := $(CXL_CORE_SRC)/port.o
cxl_core-y += $(CXL_CORE_SRC)/pmem.o
cxl_core-y += $(CXL_CORE_SRC)/regs.o
cxl_core-y += $(CXL_CORE_SRC)/memdev.o
cxl_core-y += $(CXL_CORE_SRC)/mbox.o
cxl_core-y += $(CXL_CORE_SRC)/pci.o
cxl_core-y += $(CXL_CORE_SRC)/hdm.o
cxl_core-y += $(CXL_CORE_SRC)/pmu.o
cxl_core-y += $(CXL_CORE_SRC)/cdat.o
cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o
cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o $(CXL_CORE_SRC)/region_pmem.o $(CXL_CORE_SRC)/region_dax.o
cxl_core-$(CONFIG_CXL_MCE) += $(CXL_CORE_SRC)/mce.o
cxl_core-$(CONFIG_CXL_FEATURES) += $(CXL_CORE_SRC)/features.o
cxl_core-$(CONFIG_CXL_EDAC_MEM_FEATURES) += $(CXL_CORE_SRC)/edac.o
cxl_core-$(CONFIG_CXL_RAS) += $(CXL_CORE_SRC)/ras.o
cxl_core-$(CONFIG_CXL_RAS) += $(CXL_CORE_SRC)/ras_rch.o
cxl_core-$(CONFIG_CXL_ATL) += $(CXL_CORE_SRC)/atl.o
cxl_core-y += config_check.o
cxl_core-y += cxl_core_test.o
cxl_core-y += cxl_core_exports.o
obj-m += dax_hmem.o
dax_hmem-y := $(DAX_HMEM_SRC)/hmem.o
KBUILD_CFLAGS := $(filter-out -Wmissing-prototypes -Wmissing-declarations, $(KBUILD_CFLAGS))
obj-m += test/
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/bug.h>
void check(void)
{
/*
* These kconfig symbols must be set to "m" for cxl_test to load
* and operate.
*/
BUILD_BUG_ON(!IS_ENABLED(CONFIG_64BIT));
BUILD_BUG_ON(!IS_MODULE(CONFIG_CXL_BUS));
BUILD_BUG_ON(!IS_MODULE(CONFIG_CXL_ACPI));
BUILD_BUG_ON(!IS_MODULE(CONFIG_CXL_PMEM));
BUILD_BUG_ON(!IS_ENABLED(CONFIG_CXL_REGION_INVALIDATION_TEST));
BUILD_BUG_ON(!IS_ENABLED(CONFIG_NVDIMM_SECURITY_TEST));
BUILD_BUG_ON(!IS_ENABLED(CONFIG_DEBUG_FS));
BUILD_BUG_ON(!IS_ENABLED(CONFIG_MEMORY_HOTPLUG));
}
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include "watermark.h"
cxl_test_watermark(cxl_acpi);
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include "cxl.h"
/* Exporting of cxl_core symbols that are only used by cxl_test */
EXPORT_SYMBOL_NS_GPL(cxl_num_decoders_committed, "CXL");
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include "watermark.h"
cxl_test_watermark(cxl_core);
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include "watermark.h"
cxl_test_watermark(cxl_mem);
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include "watermark.h"
cxl_test_watermark(cxl_pmem);
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include "watermark.h"
cxl_test_watermark(cxl_port);
+35
View File
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2021 Intel Corporation. All rights reserved. */
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/acpi.h>
#include <cxl.h>
#include "test/mock.h"
struct acpi_device *to_cxl_host_bridge(struct device *host, struct device *dev)
{
int index;
struct acpi_device *adev, *found = NULL;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops && ops->is_mock_bridge(dev)) {
found = ACPI_COMPANION(dev);
goto out;
}
if (dev_is_platform(dev))
goto out;
adev = to_acpi_device(dev);
if (!acpi_pci_find_root(adev->handle))
goto out;
if (strcmp(acpi_device_hid(adev), "ACPI0016") == 0) {
found = adev;
dev_dbg(host, "found host bridge %s\n", dev_name(&adev->dev));
}
out:
put_cxl_mock_ops(index);
return found;
}
+14
View File
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
ccflags-y := -I$(srctree)/drivers/cxl/ -I$(srctree)/drivers/cxl/core
obj-m += cxl_test.o
obj-m += cxl_mock.o
obj-m += cxl_mock_mem.o
obj-m += cxl_translate.o
cxl_test-y := cxl.o
cxl_test-y += hmem_test.o
cxl_mock-y := mock.o
cxl_mock_mem-y := mem.o
KBUILD_CFLAGS := $(filter-out -Wmissing-prototypes -Wmissing-declarations, $(KBUILD_CFLAGS))
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,451 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright(c) 2025 Intel Corporation. All rights reserved.
/* Preface all log entries with "cxl_translate" */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/moduleparam.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <cxlmem.h>
#include <cxl.h>
/* Maximum number of test vectors and entry length */
#define MAX_TABLE_ENTRIES 128
#define MAX_ENTRY_LEN 128
/* Expected number of parameters in each test vector */
#define EXPECTED_PARAMS 7
/* Module parameters for test vectors */
static char *table[MAX_TABLE_ENTRIES];
static int table_num;
/* Interleave Arithmetic */
#define MODULO_MATH 0
#define XOR_MATH 1
/*
* XOR mapping configuration
* The test data sets all use the same set of xormaps. When additional
* data sets arrive for validation, this static setup will need to
* be changed to accept xormaps as additional parameters.
*/
struct cxl_cxims_data *cximsd;
static u64 xormaps[] = {
0x2020900,
0x4041200,
0x1010400,
0x800,
};
static int nr_maps = ARRAY_SIZE(xormaps);
#define HBIW_TO_NR_MAPS_SIZE (CXL_DECODER_MAX_INTERLEAVE + 1)
static const int hbiw_to_nr_maps[HBIW_TO_NR_MAPS_SIZE] = {
[1] = 0, [2] = 1, [3] = 0, [4] = 2, [6] = 1, [8] = 3, [12] = 2, [16] = 4
};
/**
* to_hpa - calculate an HPA offset from a DPA offset and position
*
* dpa_offset: device physical address offset
* pos: devices position in interleave
* r_eiw: region encoded interleave ways
* r_eig: region encoded interleave granularity
* hb_ways: host bridge interleave ways
* math: interleave arithmetic (MODULO_MATH or XOR_MATH)
*
* Returns: host physical address offset
*/
static u64 to_hpa(u64 dpa_offset, int pos, u8 r_eiw, u16 r_eig, u8 hb_ways,
u8 math)
{
u64 hpa_offset;
/* Calculate base HPA offset from DPA and position */
hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, r_eiw, r_eig);
if (hpa_offset == ULLONG_MAX)
return ULLONG_MAX;
if (math == XOR_MATH) {
cximsd->nr_maps = hbiw_to_nr_maps[hb_ways];
if (cximsd->nr_maps)
return cxl_do_xormap_calc(cximsd, hpa_offset, hb_ways);
}
return hpa_offset;
}
/**
* to_dpa - translate an HPA offset to DPA offset
*
* hpa_offset: host physical address offset
* r_eiw: region encoded interleave ways
* r_eig: region encoded interleave granularity
* hb_ways: host bridge interleave ways
* math: interleave arithmetic (MODULO_MATH or XOR_MATH)
*
* Returns: device physical address offset
*/
static u64 to_dpa(u64 hpa_offset, u8 r_eiw, u16 r_eig, u8 hb_ways, u8 math)
{
u64 offset = hpa_offset;
if (math == XOR_MATH) {
cximsd->nr_maps = hbiw_to_nr_maps[hb_ways];
if (cximsd->nr_maps)
offset =
cxl_do_xormap_calc(cximsd, hpa_offset, hb_ways);
}
return cxl_calculate_dpa_offset(offset, r_eiw, r_eig);
}
/**
* to_pos - extract an interleave position from an HPA offset
*
* hpa_offset: host physical address offset
* r_eiw: region encoded interleave ways
* r_eig: region encoded interleave granularity
* hb_ways: host bridge interleave ways
* math: interleave arithmetic (MODULO_MATH or XOR_MATH)
*
* Returns: devices position in region interleave
*/
static u64 to_pos(u64 hpa_offset, u8 r_eiw, u16 r_eig, u8 hb_ways, u8 math)
{
u64 offset = hpa_offset;
/* Reverse XOR mapping if specified */
if (math == XOR_MATH)
offset = cxl_do_xormap_calc(cximsd, hpa_offset, hb_ways);
return cxl_calculate_position(offset, r_eiw, r_eig);
}
/**
* run_translation_test - execute forward and reverse translations
*
* @dpa: device physical address
* @pos: expected position in region interleave
* @r_eiw: region encoded interleave ways
* @r_eig: region encoded interleave granularity
* @hb_ways: host bridge interleave ways
* @math: interleave arithmetic (MODULO_MATH or XOR_MATH)
* @expect_spa: expected system physical address
*
* Returns: 0 on success, -1 on failure
*/
static int run_translation_test(u64 dpa, int pos, u8 r_eiw, u16 r_eig,
u8 hb_ways, int math, u64 expect_hpa)
{
u64 translated_spa, reverse_dpa;
int reverse_pos;
/* Test Device to Host translation: DPA + POS -> SPA */
translated_spa = to_hpa(dpa, pos, r_eiw, r_eig, hb_ways, math);
if (translated_spa != expect_hpa) {
pr_err("Device to host failed: expected HPA %llu, got %llu\n",
expect_hpa, translated_spa);
return -1;
}
/* Test Host to Device DPA translation: SPA -> DPA */
reverse_dpa = to_dpa(translated_spa, r_eiw, r_eig, hb_ways, math);
if (reverse_dpa != dpa) {
pr_err("Host to Device DPA failed: expected %llu, got %llu\n",
dpa, reverse_dpa);
return -1;
}
/* Test Host to Device Position translation: SPA -> POS */
reverse_pos = to_pos(translated_spa, r_eiw, r_eig, hb_ways, math);
if (reverse_pos != pos) {
pr_err("Position lookup failed: expected %d, got %d\n", pos,
reverse_pos);
return -1;
}
return 0;
}
/**
* parse_test_vector - parse a single test vector string
*
* entry: test vector string to parse
* dpa: device physical address
* pos: expected position in region interleave
* r_eiw: region encoded interleave ways
* r_eig: region encoded interleave granularity
* hb_ways: host bridge interleave ways
* math: interleave arithmetic (MODULO_MATH or XOR_MATH)
* expect_spa: expected system physical address
*
* Returns: 0 on success, negative error code on failure
*/
static int parse_test_vector(const char *entry, u64 *dpa, int *pos, u8 *r_eiw,
u16 *r_eig, u8 *hb_ways, int *math,
u64 *expect_hpa)
{
unsigned int tmp_r_eiw, tmp_r_eig, tmp_hb_ways;
int parsed;
parsed = sscanf(entry, "%llu %d %u %u %u %d %llu", dpa, pos, &tmp_r_eiw,
&tmp_r_eig, &tmp_hb_ways, math, expect_hpa);
if (parsed != EXPECTED_PARAMS) {
pr_err("Parse error: expected %d parameters, got %d in '%s'\n",
EXPECTED_PARAMS, parsed, entry);
return -EINVAL;
}
if (tmp_r_eiw > U8_MAX || tmp_r_eig > U16_MAX || tmp_hb_ways > U8_MAX) {
pr_err("Parameter overflow in entry: '%s'\n", entry);
return -ERANGE;
}
if (*math != MODULO_MATH && *math != XOR_MATH) {
pr_err("Invalid math type %d in entry: '%s'\n", *math, entry);
return -EINVAL;
}
*r_eiw = tmp_r_eiw;
*r_eig = tmp_r_eig;
*hb_ways = tmp_hb_ways;
return 0;
}
/*
* setup_xor_mapping - Initialize XOR mapping data structure
*
* The test data sets all use the same HBIG so we can use one set
* of xormaps, and set the number to apply based on HBIW before
* calling cxl_do_xormap_calc().
*
* When additional data sets arrive for validation with different
* HBIG's this static setup will need to be updated.
*
* Returns: 0 on success, negative error code on failure
*/
static int setup_xor_mapping(void)
{
if (nr_maps <= 0)
return -EINVAL;
cximsd = kzalloc(struct_size(cximsd, xormaps, nr_maps), GFP_KERNEL);
if (!cximsd)
return -ENOMEM;
cximsd->nr_maps = nr_maps;
memcpy(cximsd->xormaps, xormaps, nr_maps * sizeof(*cximsd->xormaps));
return 0;
}
static int test_random_params(void)
{
u8 valid_eiws[] = { 0, 1, 2, 3, 4, 8, 9, 10 };
u16 valid_eigs[] = { 0, 1, 2, 3, 4, 5, 6 };
int i, ways, pos, reverse_pos;
u64 dpa, hpa, reverse_dpa;
int iterations = 10000;
int failures = 0;
for (i = 0; i < iterations; i++) {
/* Generate valid random parameters for eiw, eig, pos, dpa */
u8 eiw = valid_eiws[get_random_u32() % ARRAY_SIZE(valid_eiws)];
u16 eig = valid_eigs[get_random_u32() % ARRAY_SIZE(valid_eigs)];
eiw_to_ways(eiw, &ways);
pos = get_random_u32() % ways;
dpa = get_random_u64() >> 12;
reverse_dpa = ULLONG_MAX;
reverse_pos = -1;
hpa = cxl_calculate_hpa_offset(dpa, pos, eiw, eig);
if (hpa != ULLONG_MAX) {
reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig);
reverse_pos = cxl_calculate_position(hpa, eiw, eig);
if (reverse_dpa == dpa && reverse_pos == pos)
continue;
}
pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n",
i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw, eig);
if (failures++ > 10) {
pr_err("test random too many failures, stop\n");
break;
}
}
pr_info("..... test random: PASS %d FAIL %d\n", i - failures, failures);
if (failures)
return -EINVAL;
return 0;
}
struct param_test {
u8 eiw;
u16 eig;
int pos;
bool expect; /* true: expect pass, false: expect fail */
const char *desc;
};
static struct param_test param_tests[] = {
{ 0x0, 0, 0, true, "1-way, min eig=0, pos=0" },
{ 0x0, 3, 0, true, "1-way, mid eig=3, pos=0" },
{ 0x0, 6, 0, true, "1-way, max eig=6, pos=0" },
{ 0x1, 0, 0, true, "2-way, eig=0, pos=0" },
{ 0x1, 3, 1, true, "2-way, eig=3, max pos=1" },
{ 0x1, 6, 1, true, "2-way, eig=6, max pos=1" },
{ 0x2, 0, 0, true, "4-way, eig=0, pos=0" },
{ 0x2, 3, 3, true, "4-way, eig=3, max pos=3" },
{ 0x2, 6, 3, true, "4-way, eig=6, max pos=3" },
{ 0x3, 0, 0, true, "8-way, eig=0, pos=0" },
{ 0x3, 3, 7, true, "8-way, eig=3, max pos=7" },
{ 0x3, 6, 7, true, "8-way, eig=6, max pos=7" },
{ 0x4, 0, 0, true, "16-way, eig=0, pos=0" },
{ 0x4, 3, 15, true, "16-way, eig=3, max pos=15" },
{ 0x4, 6, 15, true, "16-way, eig=6, max pos=15" },
{ 0x8, 0, 0, true, "3-way, eig=0, pos=0" },
{ 0x8, 3, 2, true, "3-way, eig=3, max pos=2" },
{ 0x8, 6, 2, true, "3-way, eig=6, max pos=2" },
{ 0x9, 0, 0, true, "6-way, eig=0, pos=0" },
{ 0x9, 3, 5, true, "6-way, eig=3, max pos=5" },
{ 0x9, 6, 5, true, "6-way, eig=6, max pos=5" },
{ 0xA, 0, 0, true, "12-way, eig=0, pos=0" },
{ 0xA, 3, 11, true, "12-way, eig=3, max pos=11" },
{ 0xA, 6, 11, true, "12-way, eig=6, max pos=11" },
{ 0x5, 0, 0, false, "invalid eiw=5" },
{ 0x7, 0, 0, false, "invalid eiw=7" },
{ 0xB, 0, 0, false, "invalid eiw=0xB" },
{ 0xFF, 0, 0, false, "invalid eiw=0xFF" },
{ 0x1, 7, 0, false, "invalid eig=7 (out of range)" },
{ 0x2, 0x10, 0, false, "invalid eig=0x10" },
{ 0x3, 0xFFFF, 0, false, "invalid eig=0xFFFF" },
{ 0x1, 0, -1, false, "pos < 0" },
{ 0x1, 0, 2, false, "2-way, pos=2 (>= ways)" },
{ 0x2, 0, 4, false, "4-way, pos=4 (>= ways)" },
{ 0x3, 0, 8, false, "8-way, pos=8 (>= ways)" },
{ 0x4, 0, 16, false, "16-way, pos=16 (>= ways)" },
{ 0x8, 0, 3, false, "3-way, pos=3 (>= ways)" },
{ 0x9, 0, 6, false, "6-way, pos=6 (>= ways)" },
{ 0xA, 0, 12, false, "12-way, pos=12 (>= ways)" },
};
static int test_cxl_validate_translation_params(void)
{
int i, rc, failures = 0;
bool valid;
for (i = 0; i < ARRAY_SIZE(param_tests); i++) {
struct param_test *t = &param_tests[i];
rc = cxl_validate_translation_params(t->eiw, t->eig, t->pos);
valid = (rc == 0);
if (valid != t->expect) {
pr_err("test params failed: %s\n", t->desc);
failures++;
}
}
pr_info("..... test params: PASS %d FAIL %d\n", i - failures, failures);
if (failures)
return -EINVAL;
return 0;
}
/*
* cxl_translate_init
*
* Run the internal validation tests when no params are passed.
* Otherwise, parse the parameters (test vectors), and kick off
* the translation test.
*
* Returns: 0 on success, negative error code on failure
*/
static int __init cxl_translate_init(void)
{
int rc, i;
/* If no tables are passed, validate module params only */
if (table_num == 0) {
pr_info("Internal validation test start...\n");
rc = test_cxl_validate_translation_params();
if (rc)
return rc;
rc = test_random_params();
if (rc)
return rc;
pr_info("Internal validation test completed successfully\n");
return 0;
}
pr_info("CXL translate test module loaded with %d test vectors\n",
table_num);
rc = setup_xor_mapping();
if (rc)
return rc;
/* Process each test vector */
for (i = 0; i < table_num; i++) {
u64 dpa, expect_spa;
int pos, math;
u8 r_eiw, hb_ways;
u16 r_eig;
pr_debug("Processing test vector %d: '%s'\n", i, table[i]);
/* Parse the test vector */
rc = parse_test_vector(table[i], &dpa, &pos, &r_eiw, &r_eig,
&hb_ways, &math, &expect_spa);
if (rc) {
pr_err("CXL Translate Test %d: FAIL\n"
" Failed to parse test vector '%s'\n",
i, table[i]);
continue;
}
/* Run the translation test */
rc = run_translation_test(dpa, pos, r_eiw, r_eig, hb_ways, math,
expect_spa);
if (rc) {
pr_err("CXL Translate Test %d: FAIL\n"
" dpa=%llu pos=%d r_eiw=%u r_eig=%u hb_ways=%u math=%s expect_spa=%llu\n",
i, dpa, pos, r_eiw, r_eig, hb_ways,
(math == XOR_MATH) ? "XOR" : "MODULO",
expect_spa);
} else {
pr_info("CXL Translate Test %d: PASS\n", i);
}
}
kfree(cximsd);
pr_info("CXL translate test completed\n");
return 0;
}
static void __exit cxl_translate_exit(void)
{
pr_info("CXL translate test module unloaded\n");
}
module_param_array(table, charp, &table_num, 0444);
MODULE_PARM_DESC(table, "Test vectors as space-separated decimal strings");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("cxl_test: cxl address translation test module");
MODULE_IMPORT_NS("CXL");
module_init(cxl_translate_init);
module_exit(cxl_translate_exit);
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2026 Intel Corporation */
#include <linux/moduleparam.h>
#include <linux/workqueue.h>
#include "../../../drivers/dax/bus.h"
static bool hmem_test;
static void hmem_test_work(struct work_struct *work)
{
}
static void hmem_test_release(struct device *dev)
{
struct hmem_platform_device *hpdev =
container_of(dev, typeof(*hpdev), pdev.dev);
memset(hpdev, 0, sizeof(*hpdev));
}
static struct hmem_platform_device hmem_test_device = {
.pdev = {
.name = "hmem_platform",
.id = 1,
.dev = {
.release = hmem_test_release,
},
},
.work = __WORK_INITIALIZER(hmem_test_device.work, hmem_test_work),
};
int hmem_test_init(void)
{
if (!hmem_test)
return 0;
return platform_device_register(&hmem_test_device.pdev);
}
void hmem_test_exit(void)
{
if (hmem_test)
platform_device_unregister(&hmem_test_device.pdev);
}
module_param(hmem_test, bool, 0444);
MODULE_PARM_DESC(hmem_test, "Enable/disable the dax_hmem test platform device");
File diff suppressed because it is too large Load Diff
+307
View File
@@ -0,0 +1,307 @@
// SPDX-License-Identifier: GPL-2.0-only
//Copyright(c) 2021 Intel Corporation. All rights reserved.
#include <linux/libnvdimm.h>
#include <linux/rculist.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/acpi.h>
#include <linux/pci.h>
#include <cxlmem.h>
#include <cxlpci.h>
#include "mock.h"
static LIST_HEAD(mock);
void register_cxl_mock_ops(struct cxl_mock_ops *ops)
{
list_add_rcu(&ops->list, &mock);
}
EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
DEFINE_STATIC_SRCU(cxl_mock_srcu);
void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
{
list_del_rcu(&ops->list);
synchronize_srcu(&cxl_mock_srcu);
}
EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
struct cxl_mock_ops *get_cxl_mock_ops(int *index)
{
*index = srcu_read_lock(&cxl_mock_srcu);
return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list);
}
EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
void put_cxl_mock_ops(int index)
{
srcu_read_unlock(&cxl_mock_srcu, index);
}
EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
{
struct acpi_device *adev =
container_of(fwnode, struct acpi_device, fwnode);
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
bool retval = false;
if (ops)
retval = ops->is_mock_adev(adev);
if (!retval)
retval = is_acpi_device_node(fwnode);
put_cxl_mock_ops(index);
return retval;
}
EXPORT_SYMBOL(__wrap_is_acpi_device_node);
int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
acpi_tbl_entry_handler_arg handler_arg,
void *arg)
{
int index, rc;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops)
rc = ops->acpi_table_parse_cedt(id, handler_arg, arg);
else
rc = acpi_table_parse_cedt(id, handler_arg, arg);
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI");
acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
acpi_string pathname,
struct acpi_object_list *arguments,
unsigned long long *data)
{
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
acpi_status status;
if (ops)
status = ops->acpi_evaluate_integer(handle, pathname, arguments,
data);
else
status = acpi_evaluate_integer(handle, pathname, arguments,
data);
put_cxl_mock_ops(index);
return status;
}
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;
struct acpi_pci_root *root;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops)
root = ops->acpi_pci_find_root(handle);
else
root = acpi_pci_find_root(handle);
put_cxl_mock_ops(index);
return root;
}
EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
struct nvdimm_bus *
__wrap_nvdimm_bus_register(struct device *dev,
struct nvdimm_bus_descriptor *nd_desc)
{
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops && ops->is_mock_dev(dev->parent->parent))
nd_desc->provider_name = "cxl_test";
put_cxl_mock_ops(index);
return nvdimm_bus_register(dev, nd_desc);
}
EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
int __wrap_devm_cxl_switch_port_decoders_setup(struct cxl_port *port)
{
int rc, index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops && ops->is_mock_port(port->uport_dev))
rc = ops->devm_cxl_switch_port_decoders_setup(port);
else
rc = devm_cxl_switch_port_decoders_setup(port);
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_switch_port_decoders_setup, "CXL");
int __wrap_devm_cxl_endpoint_decoders_setup(struct cxl_port *port)
{
int rc, index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops && ops->is_mock_port(port->uport_dev))
rc = ops->devm_cxl_endpoint_decoders_setup(port);
else
rc = devm_cxl_endpoint_decoders_setup(port);
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_endpoint_decoders_setup, "CXL");
int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)
{
int rc, index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops && ops->is_mock_dev(cxlds->dev))
rc = 0;
else
rc = cxl_await_media_ready(cxlds);
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, "CXL");
struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port,
struct device *dport_dev,
int port_id,
resource_size_t rcrb)
{
int index;
struct cxl_dport *dport;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops && ops->is_mock_port(dport_dev)) {
dport = devm_cxl_add_dport(port, dport_dev, port_id,
CXL_RESOURCE_NONE);
if (!IS_ERR(dport)) {
dport->rcrb.base = rcrb;
dport->rch = true;
}
} else
dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb);
put_cxl_mock_ops(index);
return dport;
}
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, "CXL");
void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)
{
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
if (ops && ops->is_mock_dev(cxlmd->dev.parent))
ops->cxl_endpoint_parse_cdat(port);
else
cxl_endpoint_parse_cdat(port);
put_cxl_mock_ops(index);
}
EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
struct cxl_dport *__wrap_devm_cxl_add_dport_by_dev(struct cxl_port *port,
struct device *dport_dev)
{
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
struct cxl_dport *dport;
if (ops && ops->is_mock_port(port->uport_dev))
dport = ops->devm_cxl_add_dport_by_dev(port, dport_dev);
else
dport = devm_cxl_add_dport_by_dev(port, dport_dev);
put_cxl_mock_ops(index);
return dport;
}
EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_dport_by_dev, "CXL");
int __wrap_region_intersects(resource_size_t start, size_t size,
unsigned long flags, unsigned long desc)
{
int rc = -1;
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops)
rc = ops->region_intersects(start, size, flags, desc);
if (rc < 0)
rc = region_intersects(start, size, flags, desc);
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_GPL(__wrap_region_intersects);
int __wrap_region_intersects_soft_reserve(resource_size_t start, size_t size)
{
int rc = -1;
int index;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (ops)
rc = ops->region_intersects_soft_reserve(start, size);
if (rc < 0)
rc = region_intersects_soft_reserve(start, size);
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_GPL(__wrap_region_intersects_soft_reserve);
int __wrap_walk_hmem_resources(struct device *host, walk_hmem_fn fn)
{
int index, rc = 0;
bool is_mock = strcmp(dev_name(host), "hmem_platform.1") == 0;
struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
if (is_mock) {
if (ops)
rc = ops->walk_hmem_resources(host, fn);
} else {
rc = walk_hmem_resources(host, fn);
}
put_cxl_mock_ops(index);
return rc;
}
EXPORT_SYMBOL_GPL(__wrap_walk_hmem_resources);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("cxl_test: emulation module");
MODULE_IMPORT_NS("ACPI");
MODULE_IMPORT_NS("CXL");
+43
View File
@@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/list.h>
#include <linux/acpi.h>
#include <linux/dax.h>
#include <cxl.h>
struct cxl_mock_ops {
struct list_head list;
bool (*is_mock_adev)(struct acpi_device *dev);
int (*acpi_table_parse_cedt)(enum acpi_cedt_type id,
acpi_tbl_entry_handler_arg handler_arg,
void *arg);
bool (*is_mock_bridge)(struct device *dev);
acpi_status (*acpi_evaluate_integer)(acpi_handle handle,
acpi_string pathname,
struct acpi_object_list *arguments,
unsigned long long *data);
struct acpi_pci_root *(*acpi_pci_find_root)(acpi_handle handle);
bool (*is_mock_bus)(struct pci_bus *bus);
bool (*is_mock_port)(struct device *dev);
bool (*is_mock_dev)(struct device *dev);
int (*devm_cxl_switch_port_decoders_setup)(struct cxl_port *port);
int (*devm_cxl_endpoint_decoders_setup)(struct cxl_port *port);
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);
int (*walk_hmem_resources)(struct device *host, walk_hmem_fn fn);
int (*region_intersects)(resource_size_t start, size_t size,
unsigned long flags, unsigned long desc);
int (*region_intersects_soft_reserve)(resource_size_t start,
size_t size);
};
int hmem_test_init(void);
void hmem_test_exit(void);
void register_cxl_mock_ops(struct cxl_mock_ops *ops);
void unregister_cxl_mock_ops(struct cxl_mock_ops *ops);
struct cxl_mock_ops *get_cxl_mock_ops(int *index);
void put_cxl_mock_ops(int index);
+25
View File
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#ifndef _TEST_CXL_WATERMARK_H_
#define _TEST_CXL_WATERMARK_H_
#include <linux/module.h>
#include <linux/printk.h>
int cxl_acpi_test(void);
int cxl_core_test(void);
int cxl_mem_test(void);
int cxl_pmem_test(void);
int cxl_port_test(void);
/*
* dummy routine for cxl_test to validate it is linking to the properly
* mocked module and not the standard one from the base tree.
*/
#define cxl_test_watermark(x) \
int x##_test(void) \
{ \
pr_debug("%s for cxl_test\n", KBUILD_MODNAME); \
return 0; \
} \
EXPORT_SYMBOL(x##_test)
#endif /* _TEST_CXL_WATERMARK_H_ */