|
@@ -357,12 +357,16 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns)
|
|
struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
|
|
struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
|
|
struct nd_pfn *nd_pfn = to_nd_pfn(ndns->claim);
|
|
struct nd_pfn *nd_pfn = to_nd_pfn(ndns->claim);
|
|
struct device *dev = &nd_pfn->dev;
|
|
struct device *dev = &nd_pfn->dev;
|
|
- struct vmem_altmap *altmap;
|
|
|
|
struct nd_region *nd_region;
|
|
struct nd_region *nd_region;
|
|
|
|
+ struct vmem_altmap *altmap;
|
|
struct nd_pfn_sb *pfn_sb;
|
|
struct nd_pfn_sb *pfn_sb;
|
|
struct pmem_device *pmem;
|
|
struct pmem_device *pmem;
|
|
phys_addr_t offset;
|
|
phys_addr_t offset;
|
|
int rc;
|
|
int rc;
|
|
|
|
+ struct vmem_altmap __altmap = {
|
|
|
|
+ .base_pfn = __phys_to_pfn(nsio->res.start),
|
|
|
|
+ .reserve = __phys_to_pfn(SZ_8K),
|
|
|
|
+ };
|
|
|
|
|
|
if (!nd_pfn->uuid || !nd_pfn->ndns)
|
|
if (!nd_pfn->uuid || !nd_pfn->ndns)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
@@ -380,6 +384,17 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns);
|
|
nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns);
|
|
altmap = NULL;
|
|
altmap = NULL;
|
|
|
|
+ } else if (nd_pfn->mode == PFN_MODE_PMEM) {
|
|
|
|
+ nd_pfn->npfns = (resource_size(&nsio->res) - offset)
|
|
|
|
+ / PAGE_SIZE;
|
|
|
|
+ if (le64_to_cpu(nd_pfn->pfn_sb->npfns) > nd_pfn->npfns)
|
|
|
|
+ dev_info(&nd_pfn->dev,
|
|
|
|
+ "number of pfns truncated from %lld to %ld\n",
|
|
|
|
+ le64_to_cpu(nd_pfn->pfn_sb->npfns),
|
|
|
|
+ nd_pfn->npfns);
|
|
|
|
+ altmap = & __altmap;
|
|
|
|
+ altmap->free = __phys_to_pfn(offset - SZ_8K);
|
|
|
|
+ altmap->alloc = 0;
|
|
} else {
|
|
} else {
|
|
rc = -ENXIO;
|
|
rc = -ENXIO;
|
|
goto err;
|
|
goto err;
|
|
@@ -389,7 +404,7 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns)
|
|
pmem = dev_get_drvdata(dev);
|
|
pmem = dev_get_drvdata(dev);
|
|
devm_memunmap(dev, (void __force *) pmem->virt_addr);
|
|
devm_memunmap(dev, (void __force *) pmem->virt_addr);
|
|
pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, &nsio->res,
|
|
pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, &nsio->res,
|
|
- NULL);
|
|
|
|
|
|
+ altmap);
|
|
pmem->pfn_flags |= PFN_MAP;
|
|
pmem->pfn_flags |= PFN_MAP;
|
|
if (IS_ERR(pmem->virt_addr)) {
|
|
if (IS_ERR(pmem->virt_addr)) {
|
|
rc = PTR_ERR(pmem->virt_addr);
|
|
rc = PTR_ERR(pmem->virt_addr);
|