Add an alignment gate to cxl_add_pending(): every extent in a tag group
must have its start_dpa and length aligned to CXL_DCD_EXTENT_ALIGN (SZ_2M,
the minimum device-dax mapping granularity on every architecture that
enables CXL DCD).  A misaligned extent makes the resulting dax device
unusable, so drop the whole group rather than accept a partial allocation
that would surface a broken dax_resource.

Based on patches by John Groves.

Signed-off-by: Ira Weiny <[email protected]>
Signed-off-by: John Groves <[email protected]>
Signed-off-by: Anisa Su <[email protected]>

---
Changes:
[anisa: split out as a separate validation step]
---
 drivers/cxl/core/mbox.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index e5edc3975e8f..421bd716a273 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -7,6 +7,7 @@
 #include <linux/unaligned.h>
 #include <linux/list.h>
 #include <linux/list_sort.h>
+#include <linux/sizes.h>
 #include <cxlpci.h>
 #include <cxlmem.h>
 #include <cxl.h>
@@ -1280,6 +1281,24 @@ static int add_to_pending_list(struct list_head 
*pending_list,
        return 0;
 }
 
+/*
+ * Device-dax requires extent boundaries aligned to its mapping granularity.
+ * Use SZ_2M as a conservative default; a tighter check that queries the
+ * cxl_dax_region / cxl_endpoint_decoder for its actual alignment would be
+ * strictly more correct, but SZ_2M is the minimum device-dax supports on
+ * every architecture that enables CXL DCD today.
+ */
+#define CXL_DCD_EXTENT_ALIGN   SZ_2M
+
+static bool cxl_extent_dcd_aligned(const struct cxl_extent *extent)
+{
+       u64 start = le64_to_cpu(extent->start_dpa);
+       u64 len = le64_to_cpu(extent->length);
+
+       return IS_ALIGNED(start, CXL_DCD_EXTENT_ALIGN) &&
+              IS_ALIGNED(len, CXL_DCD_EXTENT_ALIGN);
+}
+
 /*
  * Compare two extents by shared_extn_seq (ascending).  list_sort is
  * stable so when shared_extn_seq is 0 for every entry (non-sharable
@@ -1352,6 +1371,26 @@ static int cxl_add_pending(struct cxl_memdev_state *mds)
                extract_tag_group(pending, &tag, &group);
                list_sort(NULL, &group, extent_seq_compare);
 
+               /* Alignment gate — abort the group if any member fails */
+               bool aligned = true;
+               list_for_each_entry(pos, &group, list) {
+                       if (!cxl_extent_dcd_aligned(pos->extent)) {
+                               dev_warn(dev,
+                                        "Tag %pUb: dropping group, extent 
DPA:%#llx LEN:%#llx not %u-aligned\n",
+                                        &tag,
+                                        le64_to_cpu(pos->extent->start_dpa),
+                                        le64_to_cpu(pos->extent->length),
+                                        CXL_DCD_EXTENT_ALIGN);
+                               aligned = false;
+                               break;
+                       }
+               }
+               if (!aligned) {
+                       list_for_each_entry_safe(pos, tmp, &group, list)
+                               delete_extent_node(pos);
+                       continue;
+               }
+
                u16 logical_seq = 1;
                list_for_each_entry_safe(pos, tmp, &group, list) {
                        u16 raw = le16_to_cpu(pos->extent->shared_extn_seq);
-- 
2.43.0


Reply via email to