On Mon, Sep 12, 2016 at 7:30 PM, ryan chen <ryan.chan...@gmail.com> wrote:
> Hi all,
> Recently I'm trying to check the testing suite of nfit_test for nvdimm
> on 4.8-rc5, and system got panic once insmod nfit_test.ko ,
> I've checked the RIP, I guess it panics due to NULL
> nvdimm_map pointer, i.e., accessing nvdimm_map->mem,
> so I have a question that, should we check the return value of
> alloc_nvdimm_map if it failed:
>
> --- a/drivers/nvdimm/core.c
> +++ b/drivers/nvdimm/core.c
> @@ -171,6 +171,9 @@ void *devm_nvdimm_memremap(struct device *dev,
> resource_size_t offset,
>                 kref_get(&nvdimm_map->kref);
>         nvdimm_bus_unlock(dev);
>
> +       if (!nvdimm_map)
> +               return NULL;
> +
>         if (devm_add_action_or_reset(dev, nvdimm_map_put, nvdimm_map))
>                 return NULL;
> But why we got NULL nvdimm_map is still unknown,
> please let me know if you need any information. Thanks.

Thanks for the report.  We do need to check if alloc_nvdimm_map fails.
My guess as to why it is failing the call to request_mem_region().
Can you try the attached patch, and send the kernel log as well as the
contents of /proc/iomem?
libnvdimm: fix devm_nvdimm_memremap() error path

From: Dan Williams <dan.j.willi...@intel.com>

The internal alloc_nvdimm_map() helper might file, particularly if the
memory region is already busy.  Report request_mem_region() failures and
check for the failure.

Reported-by: Ryan Chen <ryan.chan...@gmail.com>
Signed-off-by: Dan Williams <dan.j.willi...@intel.com>
---
 drivers/nvdimm/core.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
index 715583f69d28..14066add20f0 100644
--- a/drivers/nvdimm/core.c
+++ b/drivers/nvdimm/core.c
@@ -99,8 +99,11 @@ static struct nvdimm_map *alloc_nvdimm_map(struct device *dev,
 	nvdimm_map->size = size;
 	kref_init(&nvdimm_map->kref);
 
-	if (!request_mem_region(offset, size, dev_name(&nvdimm_bus->dev)))
+	if (!request_mem_region(offset, size, dev_name(&nvdimm_bus->dev))) {
+		dev_err(&nvdimm_bus->dev, "failed to request %pa + %ld for %s\n",
+				&offset, size, dev_name(dev));
 		goto err_request_region;
+	}
 
 	if (flags)
 		nvdimm_map->mem = memremap(offset, size, flags);
@@ -171,6 +174,9 @@ void *devm_nvdimm_memremap(struct device *dev, resource_size_t offset,
 		kref_get(&nvdimm_map->kref);
 	nvdimm_bus_unlock(dev);
 
+	if (!nvdimm_map)
+		return NULL;
+
 	if (devm_add_action_or_reset(dev, nvdimm_map_put, nvdimm_map))
 		return NULL;
 

Reply via email to