Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:
"A fix and regression test case for nvdimm namespace label
compatibility.

Details:

- An "nvdimm namespace label" is metadata on an nvdimm that
provisions dimm capacity into a "namespace" that can host a block
device / dax-filesytem, or a device-dax character device.

A namespace is an object that other operating environment and
platform firmware needs to comprehend for capabilities like booting
from an nvdimm.

The label metadata contains a checksum that Linux was not
calculating correctly leading to other environments rejecting the
Linux label.

These have received a build success notification from the kbuild
robot, and a positive test result from Nick who reported the problem"

* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
nfit, libnvdimm: fix interleave set cookie calculation
tools/testing/nvdimm: make iset cookie predictable

+48 -12
+15 -1
drivers/acpi/nfit/core.c
··· 1603 1603 + num_mappings * sizeof(struct nfit_set_info_map); 1604 1604 } 1605 1605 1606 - static int cmp_map(const void *m0, const void *m1) 1606 + static int cmp_map_compat(const void *m0, const void *m1) 1607 1607 { 1608 1608 const struct nfit_set_info_map *map0 = m0; 1609 1609 const struct nfit_set_info_map *map1 = m1; 1610 1610 1611 1611 return memcmp(&map0->region_offset, &map1->region_offset, 1612 1612 sizeof(u64)); 1613 + } 1614 + 1615 + static int cmp_map(const void *m0, const void *m1) 1616 + { 1617 + const struct nfit_set_info_map *map0 = m0; 1618 + const struct nfit_set_info_map *map1 = m1; 1619 + 1620 + return map0->region_offset - map1->region_offset; 1613 1621 } 1614 1622 1615 1623 /* Retrieve the nth entry referencing this spa */ ··· 1675 1667 sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), 1676 1668 cmp_map, NULL); 1677 1669 nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); 1670 + 1671 + /* support namespaces created with the wrong sort order */ 1672 + sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), 1673 + cmp_map_compat, NULL); 1674 + nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); 1675 + 1678 1676 ndr_desc->nd_set = nd_set; 1679 1677 devm_kfree(dev, info); 1680 1678
+14 -4
drivers/nvdimm/namespace_devs.c
··· 1700 1700 struct device *create_namespace_pmem(struct nd_region *nd_region, 1701 1701 struct nd_namespace_label *nd_label) 1702 1702 { 1703 + u64 altcookie = nd_region_interleave_set_altcookie(nd_region); 1703 1704 u64 cookie = nd_region_interleave_set_cookie(nd_region); 1704 1705 struct nd_label_ent *label_ent; 1705 1706 struct nd_namespace_pmem *nspm; ··· 1719 1718 if (__le64_to_cpu(nd_label->isetcookie) != cookie) { 1720 1719 dev_dbg(&nd_region->dev, "invalid cookie in label: %pUb\n", 1721 1720 nd_label->uuid); 1722 - return ERR_PTR(-EAGAIN); 1721 + if (__le64_to_cpu(nd_label->isetcookie) != altcookie) 1722 + return ERR_PTR(-EAGAIN); 1723 + 1724 + dev_dbg(&nd_region->dev, "valid altcookie in label: %pUb\n", 1725 + nd_label->uuid); 1723 1726 } 1724 1727 1725 1728 nspm = kzalloc(sizeof(*nspm), GFP_KERNEL); ··· 1738 1733 res->name = dev_name(&nd_region->dev); 1739 1734 res->flags = IORESOURCE_MEM; 1740 1735 1741 - for (i = 0; i < nd_region->ndr_mappings; i++) 1742 - if (!has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i)) 1743 - break; 1736 + for (i = 0; i < nd_region->ndr_mappings; i++) { 1737 + if (has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i)) 1738 + continue; 1739 + if (has_uuid_at_pos(nd_region, nd_label->uuid, altcookie, i)) 1740 + continue; 1741 + break; 1742 + } 1743 + 1744 1744 if (i < nd_region->ndr_mappings) { 1745 1745 struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]); 1746 1746
+1
drivers/nvdimm/nd.h
··· 328 328 int nd_region_to_nstype(struct nd_region *nd_region); 329 329 int nd_region_register_namespaces(struct nd_region *nd_region, int *err); 330 330 u64 nd_region_interleave_set_cookie(struct nd_region *nd_region); 331 + u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region); 331 332 void nvdimm_bus_lock(struct device *dev); 332 333 void nvdimm_bus_unlock(struct device *dev); 333 334 bool is_nvdimm_bus_locked(struct device *dev);
+9
drivers/nvdimm/region_devs.c
··· 505 505 return 0; 506 506 } 507 507 508 + u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region) 509 + { 510 + struct nd_interleave_set *nd_set = nd_region->nd_set; 511 + 512 + if (nd_set) 513 + return nd_set->altcookie; 514 + return 0; 515 + } 516 + 508 517 void nd_mapping_free_labels(struct nd_mapping *nd_mapping) 509 518 { 510 519 struct nd_label_ent *label_ent, *e;
+2
include/linux/libnvdimm.h
··· 70 70 71 71 struct nd_interleave_set { 72 72 u64 cookie; 73 + /* compatibility with initial buggy Linux implementation */ 74 + u64 altcookie; 73 75 }; 74 76 75 77 struct nd_mapping_desc {
+7 -7
tools/testing/nvdimm/test/nfit.c
··· 887 887 memdev->range_index = 0+1; 888 888 memdev->region_index = 4+1; 889 889 memdev->region_size = SPA0_SIZE/2; 890 - memdev->region_offset = t->spa_set_dma[0]; 890 + memdev->region_offset = 1; 891 891 memdev->address = 0; 892 892 memdev->interleave_index = 0; 893 893 memdev->interleave_ways = 2; ··· 902 902 memdev->range_index = 0+1; 903 903 memdev->region_index = 5+1; 904 904 memdev->region_size = SPA0_SIZE/2; 905 - memdev->region_offset = t->spa_set_dma[0] + SPA0_SIZE/2; 905 + memdev->region_offset = (1 << 8); 906 906 memdev->address = 0; 907 907 memdev->interleave_index = 0; 908 908 memdev->interleave_ways = 2; ··· 917 917 memdev->range_index = 1+1; 918 918 memdev->region_index = 4+1; 919 919 memdev->region_size = SPA1_SIZE/4; 920 - memdev->region_offset = t->spa_set_dma[1]; 920 + memdev->region_offset = (1 << 16); 921 921 memdev->address = SPA0_SIZE/2; 922 922 memdev->interleave_index = 0; 923 923 memdev->interleave_ways = 4; ··· 932 932 memdev->range_index = 1+1; 933 933 memdev->region_index = 5+1; 934 934 memdev->region_size = SPA1_SIZE/4; 935 - memdev->region_offset = t->spa_set_dma[1] + SPA1_SIZE/4; 935 + memdev->region_offset = (1 << 24); 936 936 memdev->address = SPA0_SIZE/2; 937 937 memdev->interleave_index = 0; 938 938 memdev->interleave_ways = 4; ··· 947 947 memdev->range_index = 1+1; 948 948 memdev->region_index = 6+1; 949 949 memdev->region_size = SPA1_SIZE/4; 950 - memdev->region_offset = t->spa_set_dma[1] + 2*SPA1_SIZE/4; 950 + memdev->region_offset = (1ULL << 32); 951 951 memdev->address = SPA0_SIZE/2; 952 952 memdev->interleave_index = 0; 953 953 memdev->interleave_ways = 4; ··· 962 962 memdev->range_index = 1+1; 963 963 memdev->region_index = 7+1; 964 964 memdev->region_size = SPA1_SIZE/4; 965 - memdev->region_offset = t->spa_set_dma[1] + 3*SPA1_SIZE/4; 965 + memdev->region_offset = (1ULL << 40); 966 966 memdev->address = SPA0_SIZE/2; 967 967 memdev->interleave_index = 0; 968 968 memdev->interleave_ways = 4; ··· 1380 1380 memdev->range_index = 11+1; 1381 1381 memdev->region_index = 9+1; 1382 1382 memdev->region_size = SPA0_SIZE; 1383 - memdev->region_offset = t->spa_set_dma[2]; 1383 + memdev->region_offset = (1ULL << 48); 1384 1384 memdev->address = 0; 1385 1385 memdev->interleave_index = 0; 1386 1386 memdev->interleave_ways = 1;