+ num_mappings * sizeof(struct nfit_set_info_map);
 }
 
-static int cmp_map(const void *m0, const void *m1)
+static int cmp_map_compat(const void *m0, const void *m1)
 {
        const struct nfit_set_info_map *map0 = m0;
        const struct nfit_set_info_map *map1 = m1;
                        sizeof(u64));
 }
 
+static int cmp_map(const void *m0, const void *m1)
+{
+       const struct nfit_set_info_map *map0 = m0;
+       const struct nfit_set_info_map *map1 = m1;
+
+       return map0->region_offset - map1->region_offset;
+}
+
 /* Retrieve the nth entry referencing this spa */
 static struct acpi_nfit_memory_map *memdev_from_spa(
                struct acpi_nfit_desc *acpi_desc, u16 range_index, int n)
        sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
                        cmp_map, NULL);
        nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
+
+       /* support namespaces created with the wrong sort order */
+       sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
+                       cmp_map_compat, NULL);
+       nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
+
        ndr_desc->nd_set = nd_set;
        devm_kfree(dev, info);
 
 
 struct device *create_namespace_pmem(struct nd_region *nd_region,
                struct nd_namespace_label *nd_label)
 {
+       u64 altcookie = nd_region_interleave_set_altcookie(nd_region);
        u64 cookie = nd_region_interleave_set_cookie(nd_region);
        struct nd_label_ent *label_ent;
        struct nd_namespace_pmem *nspm;
        if (__le64_to_cpu(nd_label->isetcookie) != cookie) {
                dev_dbg(&nd_region->dev, "invalid cookie in label: %pUb\n",
                                nd_label->uuid);
-               return ERR_PTR(-EAGAIN);
+               if (__le64_to_cpu(nd_label->isetcookie) != altcookie)
+                       return ERR_PTR(-EAGAIN);
+
+               dev_dbg(&nd_region->dev, "valid altcookie in label: %pUb\n",
+                               nd_label->uuid);
        }
 
        nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
        res->name = dev_name(&nd_region->dev);
        res->flags = IORESOURCE_MEM;
 
-       for (i = 0; i < nd_region->ndr_mappings; i++)
-               if (!has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i))
-                       break;
+       for (i = 0; i < nd_region->ndr_mappings; i++) {
+               if (has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i))
+                       continue;
+               if (has_uuid_at_pos(nd_region, nd_label->uuid, altcookie, i))
+                       continue;
+               break;
+       }
+
        if (i < nd_region->ndr_mappings) {
                struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]);
 
 
 int nd_region_to_nstype(struct nd_region *nd_region);
 int nd_region_register_namespaces(struct nd_region *nd_region, int *err);
 u64 nd_region_interleave_set_cookie(struct nd_region *nd_region);
+u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region);
 void nvdimm_bus_lock(struct device *dev);
 void nvdimm_bus_unlock(struct device *dev);
 bool is_nvdimm_bus_locked(struct device *dev);
 
        return 0;
 }
 
+u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region)
+{
+       struct nd_interleave_set *nd_set = nd_region->nd_set;
+
+       if (nd_set)
+               return nd_set->altcookie;
+       return 0;
+}
+
 void nd_mapping_free_labels(struct nd_mapping *nd_mapping)
 {
        struct nd_label_ent *label_ent, *e;
 
 
 struct nd_interleave_set {
        u64 cookie;
+       /* compatibility with initial buggy Linux implementation */
+       u64 altcookie;
 };
 
 struct nd_mapping_desc {