/*
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
*/
+#include <linux/kstrtox.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/sort.h>
struct device_attribute *attr, const char *buf, size_t len)
{
bool force_raw;
- int rc = strtobool(buf, &force_raw);
+ int rc = kstrtobool(buf, &force_raw);
if (rc)
return rc;
rc = perf_pmu_register(&nd_pmu->pmu, nd_pmu->pmu.name, -1);
if (rc) {
- kfree(nd_pmu->pmu.attr_groups);
nvdimm_pmu_free_hotplug_memory(nd_pmu);
+ kfree(nd_pmu->pmu.attr_groups);
return rc;
}
{
perf_pmu_unregister(&nd_pmu->pmu);
nvdimm_pmu_free_hotplug_memory(nd_pmu);
+ kfree(nd_pmu->pmu.attr_groups);
kfree(nd_pmu);
}
EXPORT_SYMBOL_GPL(unregister_nvdimm_pmu);
* parent bio. Otherwise directly call nd_region flush.
*/
if (bio && bio->bi_iter.bi_sector != -1) {
- struct bio *child = bio_alloc(bio->bi_bdev, 0, REQ_PREFLUSH,
+ struct bio *child = bio_alloc(bio->bi_bdev, 0,
+ REQ_OP_WRITE | REQ_PREFLUSH,
GFP_ATOMIC);
if (!child)
#define pr_fmt(fmt) "of_pmem: " fmt
-#include <linux/of_platform.h>
-#include <linux/of_address.h>
+#include <linux/of.h>
#include <linux/libnvdimm.h>
#include <linux/module.h>
#include <linux/ioport.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
struct of_pmem_private {
u64 checksum, offset;
struct resource *res;
enum nd_pfn_mode mode;
+ resource_size_t res_size;
struct nd_namespace_io *nsio;
- unsigned long align, start_pad;
+ unsigned long align, start_pad, end_trunc;
struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
struct nd_namespace_common *ndns = nd_pfn->ndns;
const uuid_t *parent_uuid = nd_dev_to_uuid(&ndns->dev);
align = le32_to_cpu(pfn_sb->align);
offset = le64_to_cpu(pfn_sb->dataoff);
start_pad = le32_to_cpu(pfn_sb->start_pad);
+ end_trunc = le32_to_cpu(pfn_sb->end_trunc);
if (align == 0)
align = 1UL << ilog2(offset);
mode = le32_to_cpu(pfn_sb->mode);
*/
nsio = to_nd_namespace_io(&ndns->dev);
res = &nsio->res;
- if (offset >= resource_size(res)) {
+ res_size = resource_size(res);
+ if (offset >= res_size) {
dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n",
dev_name(&ndns->dev));
return -EOPNOTSUPP;
return -EOPNOTSUPP;
}
- if (!IS_ALIGNED(res->start + le32_to_cpu(pfn_sb->start_pad),
- memremap_compat_align())) {
+ if (!IS_ALIGNED(res->start + start_pad, memremap_compat_align())) {
dev_err(&nd_pfn->dev, "resource start misaligned\n");
return -EOPNOTSUPP;
}
- if (!IS_ALIGNED(res->end + 1 - le32_to_cpu(pfn_sb->end_trunc),
- memremap_compat_align())) {
+ if (!IS_ALIGNED(res->end + 1 - end_trunc, memremap_compat_align())) {
dev_err(&nd_pfn->dev, "resource end misaligned\n");
return -EOPNOTSUPP;
}
+ if (offset >= (res_size - start_pad - end_trunc)) {
+ dev_err(&nd_pfn->dev, "bad offset with small namespace\n");
+ return -EOPNOTSUPP;
+ }
return 0;
}
EXPORT_SYMBOL(nd_pfn_validate);
else
return -ENXIO;
- if (offset >= size) {
+ if (offset >= (size - end_trunc)) {
+ /* This results in zero size devices */
dev_err(&nd_pfn->dev, "%s unable to satisfy requested alignment\n",
dev_name(&ndns->dev));
return -ENXIO;
#include <linux/moduleparam.h>
#include <linux/badblocks.h>
#include <linux/memremap.h>
+#include <linux/kstrtox.h>
#include <linux/vmalloc.h>
#include <linux/blk-mq.h>
#include <linux/pfn_t.h>
bool write_cache;
int rc;
- rc = strtobool(buf, &write_cache);
+ rc = kstrtobool(buf, &write_cache);
if (rc)
return rc;
dax_write_cache(pmem->dax_dev, write_cache);
#include <linux/scatterlist.h>
#include <linux/memregion.h>
#include <linux/highmem.h>
+#include <linux/kstrtox.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/hash.h>
const char *buf, size_t len)
{
bool flush;
- int rc = strtobool(buf, &flush);
+ int rc = kstrtobool(buf, &flush);
struct nd_region *nd_region = to_nd_region(dev);
if (rc)
struct device_attribute *attr, const char *buf, size_t len)
{
bool ro;
- int rc = strtobool(buf, &ro);
+ int rc = kstrtobool(buf, &ro);
struct nd_region *nd_region = to_nd_region(dev);
if (rc)