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

Merge tag 'libnvdimm-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm updates from Dan Williams:
"Twas the day before Christmas and the only thing stirring in libnvdimm
/ device-dax land is a pile of miscellaneous fixups and cleanups.

The bulk of it has appeared in -next save the last two patches to
device-dax that have passed my build and unit tests.

- Fix a long standing block-window-namespace issue surfaced by the
ndctl change to attempt to preserve the kernel device name over
a 'reconfigure'

- Fix a few error path memory leaks in nfit and device-dax

- Silence a smatch warning in the ioctl path

- Miscellaneous cleanups"

* tag 'libnvdimm-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
device-dax: Avoid an unnecessary check in alloc_dev_dax_range()
device-dax: Fix range release
device-dax: delete a redundancy check in dev_dax_validate_align()
libnvdimm/label: Return -ENXIO for no slot in __blk_label_update
device-dax/core: Fix memory leak when rmmod dax.ko
device-dax/pmem: Convert comma to semicolon
libnvdimm: Cleanup include of badblocks.h
ACPI: NFIT: Fix input validation of bus-family
libnvdimm/namespace: Fix reaping of invalidated block-window-namespace labels
ACPI/nfit: avoid accessing uninitialized memory in acpi_nfit_ctl()

+53 -52
+10 -5
drivers/acpi/nfit/core.c
··· 5 5 #include <linux/list_sort.h> 6 6 #include <linux/libnvdimm.h> 7 7 #include <linux/module.h> 8 + #include <linux/nospec.h> 8 9 #include <linux/mutex.h> 9 10 #include <linux/ndctl.h> 10 11 #include <linux/sysfs.h> ··· 283 282 284 283 static union acpi_object *int_to_buf(union acpi_object *integer) 285 284 { 286 - union acpi_object *buf = ACPI_ALLOCATE(sizeof(*buf) + 4); 285 + union acpi_object *buf = NULL; 287 286 void *dst = NULL; 288 - 289 - if (!buf) 290 - goto err; 291 287 292 288 if (integer->type != ACPI_TYPE_INTEGER) { 293 289 WARN_ONCE(1, "BIOS bug, unexpected element type: %d\n", 294 290 integer->type); 295 291 goto err; 296 292 } 293 + 294 + buf = ACPI_ALLOCATE(sizeof(*buf) + 4); 295 + if (!buf) 296 + goto err; 297 297 298 298 dst = buf + 1; 299 299 buf->type = ACPI_TYPE_BUFFER; ··· 480 478 cmd_mask = nd_desc->cmd_mask; 481 479 if (cmd == ND_CMD_CALL && call_pkg->nd_family) { 482 480 family = call_pkg->nd_family; 483 - if (!test_bit(family, &nd_desc->bus_family_mask)) 481 + if (family > NVDIMM_BUS_FAMILY_MAX || 482 + !test_bit(family, &nd_desc->bus_family_mask)) 484 483 return -EINVAL; 484 + family = array_index_nospec(family, 485 + NVDIMM_BUS_FAMILY_MAX + 1); 485 486 dsm_mask = acpi_desc->family_dsm_mask[family]; 486 487 guid = to_nfit_bus_uuid(family); 487 488 } else {
+26 -43
drivers/dax/bus.c
··· 367 367 } 368 368 EXPORT_SYMBOL_GPL(kill_dev_dax); 369 369 370 - static void free_dev_dax_ranges(struct dev_dax *dev_dax) 370 + static void trim_dev_dax_range(struct dev_dax *dev_dax) 371 371 { 372 + int i = dev_dax->nr_range - 1; 373 + struct range *range = &dev_dax->ranges[i].range; 372 374 struct dax_region *dax_region = dev_dax->region; 373 - int i; 374 375 375 376 device_lock_assert(dax_region->dev); 376 - for (i = 0; i < dev_dax->nr_range; i++) { 377 - struct range *range = &dev_dax->ranges[i].range; 377 + dev_dbg(&dev_dax->dev, "delete range[%d]: %#llx:%#llx\n", i, 378 + (unsigned long long)range->start, 379 + (unsigned long long)range->end); 378 380 379 - __release_region(&dax_region->res, range->start, 380 - range_len(range)); 381 + __release_region(&dax_region->res, range->start, range_len(range)); 382 + if (--dev_dax->nr_range == 0) { 383 + kfree(dev_dax->ranges); 384 + dev_dax->ranges = NULL; 381 385 } 382 - dev_dax->nr_range = 0; 386 + } 387 + 388 + static void free_dev_dax_ranges(struct dev_dax *dev_dax) 389 + { 390 + while (dev_dax->nr_range) 391 + trim_dev_dax_range(dev_dax); 383 392 } 384 393 385 394 static void unregister_dev_dax(void *dev) ··· 772 763 return 0; 773 764 } 774 765 775 - ranges = krealloc(dev_dax->ranges, sizeof(*ranges) 776 - * (dev_dax->nr_range + 1), GFP_KERNEL); 777 - if (!ranges) 766 + alloc = __request_region(res, start, size, dev_name(dev), 0); 767 + if (!alloc) 778 768 return -ENOMEM; 779 769 780 - alloc = __request_region(res, start, size, dev_name(dev), 0); 781 - if (!alloc) { 782 - /* 783 - * If this was an empty set of ranges nothing else 784 - * will release @ranges, so do it now. 785 - */ 786 - if (!dev_dax->nr_range) { 787 - kfree(ranges); 788 - ranges = NULL; 789 - } 790 - dev_dax->ranges = ranges; 770 + ranges = krealloc(dev_dax->ranges, sizeof(*ranges) 771 + * (dev_dax->nr_range + 1), GFP_KERNEL); 772 + if (!ranges) { 773 + __release_region(res, alloc->start, resource_size(alloc)); 791 774 return -ENOMEM; 792 775 } 793 776 ··· 805 804 return 0; 806 805 807 806 rc = devm_register_dax_mapping(dev_dax, dev_dax->nr_range - 1); 808 - if (rc) { 809 - dev_dbg(dev, "delete range[%d]: %pa:%pa\n", dev_dax->nr_range - 1, 810 - &alloc->start, &alloc->end); 811 - dev_dax->nr_range--; 812 - __release_region(res, alloc->start, resource_size(alloc)); 813 - return rc; 814 - } 807 + if (rc) 808 + trim_dev_dax_range(dev_dax); 815 809 816 - return 0; 810 + return rc; 817 811 } 818 812 819 813 static int adjust_dev_dax_range(struct dev_dax *dev_dax, struct resource *res, resource_size_t size) ··· 881 885 if (shrink >= range_len(range)) { 882 886 devm_release_action(dax_region->dev, 883 887 unregister_dax_mapping, &mapping->dev); 884 - __release_region(&dax_region->res, range->start, 885 - range_len(range)); 886 - dev_dax->nr_range--; 887 - dev_dbg(dev, "delete range[%d]: %#llx:%#llx\n", i, 888 - (unsigned long long) range->start, 889 - (unsigned long long) range->end); 888 + trim_dev_dax_range(dev_dax); 890 889 to_shrink -= shrink; 891 890 if (!to_shrink) 892 891 break; ··· 1105 1114 1106 1115 static ssize_t dev_dax_validate_align(struct dev_dax *dev_dax) 1107 1116 { 1108 - resource_size_t dev_size = dev_dax_size(dev_dax); 1109 1117 struct device *dev = &dev_dax->dev; 1110 1118 int i; 1111 - 1112 - if (dev_size > 0 && !alloc_is_aligned(dev_dax, dev_size)) { 1113 - dev_dbg(dev, "%s: align %u invalid for size %pa\n", 1114 - __func__, dev_dax->align, &dev_size); 1115 - return -EINVAL; 1116 - } 1117 1119 1118 1120 for (i = 0; i < dev_dax->nr_range; i++) { 1119 1121 size_t len = range_len(&dev_dax->ranges[i].range); ··· 1258 1274 put_dax(dax_dev); 1259 1275 free_dev_dax_id(dev_dax); 1260 1276 dax_region_put(dax_region); 1261 - kfree(dev_dax->ranges); 1262 1277 kfree(dev_dax->pgmap); 1263 1278 kfree(dev_dax); 1264 1279 }
+1 -1
drivers/dax/pmem/core.c
··· 52 52 53 53 /* adjust the dax_region range to the start of data */ 54 54 range = pgmap.range; 55 - range.start += offset, 55 + range.start += offset; 56 56 dax_region = alloc_dax_region(dev, region_id, &range, 57 57 nd_region->target_node, le32_to_cpu(pfn_sb->align), 58 58 IORESOURCE_DAX_STATIC);
+1
drivers/dax/super.c
··· 752 752 753 753 static void __exit dax_core_exit(void) 754 754 { 755 + dax_bus_exit(); 755 756 unregister_chrdev_region(dax_devt, MINORMASK+1); 756 757 ida_destroy(&dax_minor_ida); 757 758 dax_fs_exit();
+2 -1
drivers/nvdimm/btt.h
··· 7 7 #ifndef _LINUX_BTT_H 8 8 #define _LINUX_BTT_H 9 9 10 - #include <linux/badblocks.h> 11 10 #include <linux/types.h> 12 11 13 12 #define BTT_SIG_LEN 16 ··· 195 196 struct mutex err_lock; 196 197 int log_index[2]; 197 198 }; 199 + 200 + struct badblocks; 198 201 199 202 /** 200 203 * struct btt - handle for a BTT instance
+1
drivers/nvdimm/claim.c
··· 4 4 */ 5 5 #include <linux/device.h> 6 6 #include <linux/sizes.h> 7 + #include <linux/badblocks.h> 7 8 #include "nd-core.h" 8 9 #include "pmem.h" 9 10 #include "pfn.h"
-1
drivers/nvdimm/core.c
··· 3 3 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. 4 4 */ 5 5 #include <linux/libnvdimm.h> 6 - #include <linux/badblocks.h> 7 6 #include <linux/suspend.h> 8 7 #include <linux/export.h> 9 8 #include <linux/module.h>
+12 -1
drivers/nvdimm/label.c
··· 980 980 } 981 981 } 982 982 983 + /* release slots associated with any invalidated UUIDs */ 984 + mutex_lock(&nd_mapping->lock); 985 + list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) 986 + if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags)) { 987 + reap_victim(nd_mapping, label_ent); 988 + list_move(&label_ent->list, &list); 989 + } 990 + mutex_unlock(&nd_mapping->lock); 991 + 983 992 /* 984 993 * Find the resource associated with the first label in the set 985 994 * per the v1.2 namespace specification. ··· 1008 999 if (is_old_resource(res, old_res_list, old_num_resources)) 1009 1000 continue; /* carry-over */ 1010 1001 slot = nd_label_alloc_slot(ndd); 1011 - if (slot == UINT_MAX) 1002 + if (slot == UINT_MAX) { 1003 + rc = -ENXIO; 1012 1004 goto abort; 1005 + } 1013 1006 dev_dbg(ndd->dev, "allocated: %d\n", slot); 1014 1007 1015 1008 nd_label = to_label(ndd, slot);