]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cxl/acpi: Make the XOR calculations available for testing
authorAlison Schofield <alison.schofield@intel.com>
Tue, 14 Oct 2025 08:24:31 +0000 (01:24 -0700)
committerDave Jiang <dave.jiang@intel.com>
Mon, 3 Nov 2025 16:27:32 +0000 (09:27 -0700)
In preparation for adding a test module that can exercise the address
translation functions performed by the CXL Driver, refactor the XOR
implementation like this:

- Extract the core calculation into a standalone helper function,
- Export the new function for use by test module cxl_translate only,
- Enhance the parameter validation since this new function will be
  called from a test module with no guarantee of valid parameters,
- Move the define of struct cxl_cxims_data to cxl.h so the test module
  can build xormaps.

Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/acpi.c
drivers/cxl/cxl.h

index bd2e282ca93a059f12ba96fdf2e30f4ddbbaddb9..a8069278cb565f04cb2d95b54424b4f89ea5c44a 100644 (file)
 #include "cxlpci.h"
 #include "cxl.h"
 
-struct cxl_cxims_data {
-       int nr_maps;
-       u64 xormaps[] __counted_by(nr_maps);
-};
-
 static const guid_t acpi_cxl_qtg_id_guid =
        GUID_INIT(0xF365F9A6, 0xA7DE, 0x4071,
                  0xA6, 0x6A, 0xB4, 0x0C, 0x0B, 0x4F, 0x8E, 0x52);
 
-static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr)
+#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
+};
+
+static const int valid_hbiw[] = { 1, 2, 3, 4, 6, 8, 12, 16 };
+
+u64 cxl_do_xormap_calc(struct cxl_cxims_data *cximsd, u64 addr, int hbiw)
 {
-       struct cxl_cxims_data *cximsd = cxlrd->platform_data;
-       int hbiw = cxlrd->cxlsd.nr_targets;
+       int nr_maps_to_apply = -1;
        u64 val;
        int pos;
 
-       /* No xormaps for host bridge interleave ways of 1 or 3 */
-       if (hbiw == 1 || hbiw == 3)
-               return addr;
+       /*
+        * Strictly validate hbiw since this function is used for testing and
+        * that nullifies any expectation of trusted parameters from the CXL
+        * Region Driver.
+        */
+       for (int i = 0; i < ARRAY_SIZE(valid_hbiw); i++) {
+               if (valid_hbiw[i] == hbiw) {
+                       nr_maps_to_apply = hbiw_to_nr_maps[hbiw];
+                       break;
+               }
+       }
+       if (nr_maps_to_apply == -1 || nr_maps_to_apply > cximsd->nr_maps)
+               return ULLONG_MAX;
 
        /*
         * In regions using XOR interleave arithmetic the CXL HPA may not
@@ -60,6 +71,14 @@ static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr)
 
        return addr;
 }
+EXPORT_SYMBOL_FOR_MODULES(cxl_do_xormap_calc, "cxl_translate");
+
+static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr)
+{
+       struct cxl_cxims_data *cximsd = cxlrd->platform_data;
+
+       return cxl_do_xormap_calc(cximsd, addr, cxlrd->cxlsd.nr_targets);
+}
 
 struct cxl_cxims_context {
        struct device *dev;
index 10bee9aaa943e786da1d9241eb862a8e89311a96..e8931b626fc627cd8ef5519a06ba8c4f8e081d12 100644 (file)
@@ -743,6 +743,19 @@ int cxl_validate_translation_params(u8 eiw, u16 eig, int pos);
 u64 cxl_calculate_hpa_offset(u64 dpa_offset, int pos, u8 eiw, u16 eig);
 u64 cxl_calculate_dpa_offset(u64 hpa_offset, u8 eiw, u16 eig);
 int cxl_calculate_position(u64 hpa_offset, u8 eiw, u16 eig);
+struct cxl_cxims_data {
+       int nr_maps;
+       u64 xormaps[] __counted_by(nr_maps);
+};
+
+#if IS_ENABLED(CONFIG_CXL_ACPI)
+u64 cxl_do_xormap_calc(struct cxl_cxims_data *cximsd, u64 addr, int hbiw);
+#else
+static inline u64 cxl_do_xormap_calc(struct cxl_cxims_data *cximsd, u64 addr, int hbiw)
+{
+       return ULLONG_MAX;
+}
+#endif
 
 int cxl_num_decoders_committed(struct cxl_port *port);
 bool is_cxl_port(const struct device *dev);