linux-nvdimm.lists.01.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/6] libnvdimm/namespace: Make namespace size validation arch dependent
@ 2019-11-28  8:30 Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 2/6] libnvdimm/namespace: Validate namespace start addr and size Aneesh Kumar K.V
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2019-11-28  8:30 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm, Aneesh Kumar K.V

The page size used to map the namespace is arch dependent. For example
architectures like ppc64 use 16MB page size for direct-mapping. If the namespace
size is not aligned to the mapping page size, we can observe kernel crash
during namespace init and destroy.

This is due to kernel doing partial map/unmap of the resource range

BUG: Unable to handle kernel data access at 0xc001000406000000
Faulting instruction address: 0xc000000000090790
NIP [c000000000090790] arch_add_memory+0xc0/0x130
LR [c000000000090744] arch_add_memory+0x74/0x130
Call Trace:
 arch_add_memory+0x74/0x130 (unreliable)
 memremap_pages+0x74c/0xa30
 devm_memremap_pages+0x3c/0xa0
 pmem_attach_disk+0x188/0x770
 nvdimm_bus_probe+0xd8/0x470
 really_probe+0x148/0x570
 driver_probe_device+0x19c/0x1d0
 device_driver_attach+0xcc/0x100
 bind_store+0x134/0x1c0
 drv_attr_store+0x44/0x60
 sysfs_kf_write+0x74/0xc0
 kernfs_fop_write+0x1b4/0x290
 __vfs_write+0x3c/0x70
 vfs_write+0xd0/0x260
 ksys_write+0xdc/0x130
 system_call+0x5c/0x68

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
 arch/arm64/mm/flush.c     |  6 ++++++
 arch/powerpc/lib/pmem.c   | 10 ++++++++++
 arch/x86/mm/pageattr.c    |  7 +++++++
 include/linux/libnvdimm.h |  1 +
 4 files changed, 24 insertions(+)

diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index ac485163a4a7..36b6f6353242 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -91,4 +91,10 @@ void arch_invalidate_pmem(void *addr, size_t size)
 	__inval_dcache_area(addr, size);
 }
 EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
+
+unsigned long arch_namespace_align_size(void)
+{
+	return PAGE_SIZE;
+}
+EXPORT_SYMBOL_GPL(arch_namespace_align_size);
 #endif
diff --git a/arch/powerpc/lib/pmem.c b/arch/powerpc/lib/pmem.c
index 0666a8d29596..8f09d94b1469 100644
--- a/arch/powerpc/lib/pmem.c
+++ b/arch/powerpc/lib/pmem.c
@@ -26,6 +26,16 @@ void arch_invalidate_pmem(void *addr, size_t size)
 }
 EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
 
+unsigned long arch_namespace_align_size(void)
+{
+
+	if (radix_enabled())
+		return PAGE_SIZE;
+	return (1UL << mmu_psize_defs[mmu_linear_psize].shift);
+
+}
+EXPORT_SYMBOL_GPL(arch_namespace_align_size);
+
 /*
  * CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE symbols
  */
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 0d09cc5aad61..51b8d11e7b94 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -310,6 +310,13 @@ void arch_invalidate_pmem(void *addr, size_t size)
 }
 EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
 
+unsigned long arch_namespace_align_size(void)
+{
+	return PAGE_SIZE;
+}
+EXPORT_SYMBOL_GPL(arch_namespace_align_size);
+
+
 static void __cpa_flush_all(void *arg)
 {
 	unsigned long cache = (unsigned long)arg;
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index b6eddf912568..72d583fa9954 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -291,4 +291,5 @@ static inline void arch_invalidate_pmem(void *addr, size_t size)
 }
 #endif
 
+unsigned long arch_namespace_align_size(void);
 #endif /* __LIBNVDIMM_H__ */
-- 
2.23.0
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/6] libnvdimm/namespace: Validate namespace start addr and size
  2019-11-28  8:30 [PATCH v2 1/6] libnvdimm/namespace: Make namespace size validation arch dependent Aneesh Kumar K.V
@ 2019-11-28  8:30 ` Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 3/6] libnvdimm/namespace: Validate namespace size when creating new namespace Aneesh Kumar K.V
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2019-11-28  8:30 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm, Aneesh Kumar K.V

Make sure namespace start addr and size are properly aligned as per architecture
restrictions. If the namespace is not aligned we mark the namespace 'disabled'

Architectures like ppc64 use different page size than PAGE_SIZE to map
direct-map address range. The kernel needs to make sure the namespace size is aligned
correctly for the direct-map page size.

kernel log will contain information as below.

[    5.810939] nd_pmem namespace0.1: invalid size/SPA
[    5.810969] nd_pmem: probe of namespace0.1 failed with error -95

and the namespace will be marked 'disabled'

  {
    "dev":"namespace0.1",
    "mode":"fsdax",
    "map":"mem",
    "size":1071644672,
    "uuid":"25577a00-c012-421d-89ca-3ee189e08848",
    "sector_size":512,
    "state":"disabled"
  },

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
 drivers/nvdimm/namespace_devs.c | 39 +++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index cca0a3ba1d2c..d77d9c9e449d 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1139,6 +1139,40 @@ resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns)
 }
 EXPORT_SYMBOL(nvdimm_namespace_capacity);
 
+static bool nvdimm_valid_namespace(struct nd_namespace_common *ndns, resource_size_t size)
+{
+	struct device *dev = &ndns->dev;
+	struct nd_region *nd_region = to_nd_region(dev->parent);
+	unsigned long align_size = arch_namespace_align_size();
+	struct resource *res;
+	u32 remainder;
+
+	if (is_namespace_blk(dev))
+		return true;
+
+	div_u64_rem(size, align_size * nd_region->ndr_mappings, &remainder);
+	if (remainder)
+		return false;
+
+	if (is_namespace_pmem(dev)) {
+		struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
+
+		res = &nspm->nsio.res;
+	} else if (is_namespace_io(dev)) {
+		struct nd_namespace_io *nsio = to_nd_namespace_io(dev);
+
+		res = &nsio->res;
+	} else
+		/* cannot reach */
+		return false;
+
+	div_u64_rem(res->start, align_size * nd_region->ndr_mappings, &remainder);
+	if (remainder)
+		return false;
+
+	return true;
+}
+
 bool nvdimm_namespace_locked(struct nd_namespace_common *ndns)
 {
 	int i;
@@ -1735,6 +1769,11 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev)
 		return ERR_PTR(-ENODEV);
 	}
 
+	if (!nvdimm_valid_namespace(ndns, size)) {
+		dev_err(&ndns->dev, "invalid size/SPA");
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+
 	if (is_namespace_pmem(&ndns->dev)) {
 		struct nd_namespace_pmem *nspm;
 
-- 
2.23.0
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/6] libnvdimm/namespace: Validate namespace size when creating new namespace.
  2019-11-28  8:30 [PATCH v2 1/6] libnvdimm/namespace: Make namespace size validation arch dependent Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 2/6] libnvdimm/namespace: Validate namespace start addr and size Aneesh Kumar K.V
@ 2019-11-28  8:30 ` Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 4/6] libnvdimm/namespace: Add debug check while initializing namespace resource size Aneesh Kumar K.V
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2019-11-28  8:30 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm, Aneesh Kumar K.V

Architectures like ppc64 use different page size than PAGE_SIZE to map
direct-map address range. The kernel needs to make sure the namespace size is aligned
correctly for the direct-map page size.

kernel log will contain the below details
[  939.620064] nd namespace0.3: 1071644672 is not 16384K aligned

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
 drivers/nvdimm/namespace_devs.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index d77d9c9e449d..0e4c04765cb8 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -917,6 +917,17 @@ static int grow_dpa_allocation(struct nd_region *nd_region,
 	return 0;
 }
 
+static unsigned long nvdimm_validate_namespace_size(struct nd_region *nd_region,
+		unsigned long size, unsigned long align_size)
+{
+	u32 remainder;
+
+	div_u64_rem(size, align_size * nd_region->ndr_mappings, &remainder);
+	if (remainder)
+		return align_size * nd_region->ndr_mappings;
+	return 0;
+}
+
 static void nd_namespace_pmem_set_resource(struct nd_region *nd_region,
 		struct nd_namespace_pmem *nspm, resource_size_t size)
 {
@@ -975,7 +986,8 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
 	struct nd_mapping *nd_mapping;
 	struct nvdimm_drvdata *ndd;
 	struct nd_label_id label_id;
-	u32 flags = 0, remainder;
+	unsigned long map_size;
+	u32 flags = 0;
 	int rc, i, id = -1;
 	u8 *uuid = NULL;
 
@@ -1006,10 +1018,9 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
 		return -ENXIO;
 	}
 
-	div_u64_rem(val, PAGE_SIZE * nd_region->ndr_mappings, &remainder);
-	if (remainder) {
-		dev_dbg(dev, "%llu is not %ldK aligned\n", val,
-				(PAGE_SIZE * nd_region->ndr_mappings) / SZ_1K);
+	map_size = nvdimm_validate_namespace_size(nd_region, val, arch_namespace_align_size());
+	if (map_size) {
+		dev_err(dev, "%llu is not %ldK aligned\n", val, map_size / SZ_1K);
 		return -EINVAL;
 	}
 
-- 
2.23.0
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/6] libnvdimm/namespace: Add debug check while initializing namespace resource size.
  2019-11-28  8:30 [PATCH v2 1/6] libnvdimm/namespace: Make namespace size validation arch dependent Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 2/6] libnvdimm/namespace: Validate namespace start addr and size Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 3/6] libnvdimm/namespace: Validate namespace size when creating new namespace Aneesh Kumar K.V
@ 2019-11-28  8:30 ` Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 5/6] libnvdimm/namespace: Align DPA based on arch restrictions Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 6/6] libnvdimm/namespace: Expose arch specific supported size align value Aneesh Kumar K.V
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2019-11-28  8:30 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm, Aneesh Kumar K.V

This should enable us to catch if we are initializing the namespace with a wrong
size.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
 drivers/nvdimm/namespace_devs.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 0e4c04765cb8..06b55c41660d 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -967,6 +967,18 @@ static void nd_namespace_pmem_set_resource(struct nd_region *nd_region,
  out:
 	res->start = nd_region->ndr_start + offset;
 	res->end = res->start + size - 1;
+#ifdef CONFIG_DEBUG_VM
+	if (size) {
+		unsigned long map_size;
+
+		map_size = nvdimm_validate_namespace_size(nd_region, size, arch_namespace_align_size());
+		WARN_ON(map_size);
+
+		map_size = nvdimm_validate_namespace_size(nd_region, res->start, arch_namespace_align_size());
+		WARN_ON(map_size);
+
+	}
+#endif
 }
 
 static bool uuid_not_set(const u8 *uuid, struct device *dev, const char *where)
-- 
2.23.0
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 5/6] libnvdimm/namespace: Align DPA based on arch restrictions
  2019-11-28  8:30 [PATCH v2 1/6] libnvdimm/namespace: Make namespace size validation arch dependent Aneesh Kumar K.V
                   ` (2 preceding siblings ...)
  2019-11-28  8:30 ` [PATCH v2 4/6] libnvdimm/namespace: Add debug check while initializing namespace resource size Aneesh Kumar K.V
@ 2019-11-28  8:30 ` Aneesh Kumar K.V
  2019-11-28  8:30 ` [PATCH v2 6/6] libnvdimm/namespace: Expose arch specific supported size align value Aneesh Kumar K.V
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2019-11-28  8:30 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm, Aneesh Kumar K.V

When creating new namespace make sure DPA address are properly aligned based
on arch restrictions.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
 drivers/nvdimm/namespace_devs.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 06b55c41660d..6a83db9f8734 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -589,6 +589,8 @@ static void space_valid(struct nd_region *nd_region, struct nvdimm_drvdata *ndd,
 		return;
 	}
 
+	valid->start = ALIGN(valid->start, arch_namespace_align_size());
+
 	/* allocation needs to be contiguous, so this is all or nothing */
 	if (resource_size(valid) < n)
 		goto invalid;
-- 
2.23.0
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 6/6] libnvdimm/namespace: Expose arch specific supported size align value
  2019-11-28  8:30 [PATCH v2 1/6] libnvdimm/namespace: Make namespace size validation arch dependent Aneesh Kumar K.V
                   ` (3 preceding siblings ...)
  2019-11-28  8:30 ` [PATCH v2 5/6] libnvdimm/namespace: Align DPA based on arch restrictions Aneesh Kumar K.V
@ 2019-11-28  8:30 ` Aneesh Kumar K.V
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2019-11-28  8:30 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm, Aneesh Kumar K.V

Expose supported size align as a namespace RO attribute. Usespace can use this
to validate the size argument specified when creating a new namespace.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
 drivers/nvdimm/namespace_devs.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 6a83db9f8734..22c714469f87 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1684,6 +1684,14 @@ static ssize_t force_raw_show(struct device *dev,
 }
 static DEVICE_ATTR_RW(force_raw);
 
+static ssize_t supported_size_align_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%ld\n", arch_namespace_align_size());
+}
+static DEVICE_ATTR_RO(supported_size_align);
+
+
 static struct attribute *nd_namespace_attributes[] = {
 	&dev_attr_nstype.attr,
 	&dev_attr_size.attr,
@@ -1696,6 +1704,7 @@ static struct attribute *nd_namespace_attributes[] = {
 	&dev_attr_sector_size.attr,
 	&dev_attr_dpa_extents.attr,
 	&dev_attr_holder_class.attr,
+	&dev_attr_supported_size_align.attr,
 	NULL,
 };
 
-- 
2.23.0
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-11-28  8:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-28  8:30 [PATCH v2 1/6] libnvdimm/namespace: Make namespace size validation arch dependent Aneesh Kumar K.V
2019-11-28  8:30 ` [PATCH v2 2/6] libnvdimm/namespace: Validate namespace start addr and size Aneesh Kumar K.V
2019-11-28  8:30 ` [PATCH v2 3/6] libnvdimm/namespace: Validate namespace size when creating new namespace Aneesh Kumar K.V
2019-11-28  8:30 ` [PATCH v2 4/6] libnvdimm/namespace: Add debug check while initializing namespace resource size Aneesh Kumar K.V
2019-11-28  8:30 ` [PATCH v2 5/6] libnvdimm/namespace: Align DPA based on arch restrictions Aneesh Kumar K.V
2019-11-28  8:30 ` [PATCH v2 6/6] libnvdimm/namespace: Expose arch specific supported size align value Aneesh Kumar K.V

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).