Pull libnvdimm fixes from Dan Williams: "1/ Two regression fixes since v4.6: one for the byte order of a sysfs attribute (bz121161) and another for QEMU 2.6's NVDIMM _DSM (ACPI Device Specific Method) implementation that gets tripped up by new auto-probing behavior in the NFIT driver. 2/ A fix tagged for -stable that stops the kernel from clobbering/ignoring changes to the configuration of a 'pfn' instance ("struct page" driver). For example changing the alignment from 2M to 1G may silently revert to 2M if that value is currently stored on media. 3/ A fix from Eric for an xfstests failure in dax. It is not currently tagged for -stable since it requires an 8-exabyte file system to trigger, and there appear to be no user visible side effects" * 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: nfit: fix format interface code byte order dax: fix offset overflow in dax_io acpi, nfit: fix acpi_check_dsm() vs zero functions implemented libnvdimm, pfn, dax: fix initialization vs autodetect for mode + alignment
Unified · Split
| @@ -928,7 +928,7 @@ static ssize_t format_show(struct device *dev, · 927 unmodified lines | ||
| 928 | 928 | { |
| 929 | 929 | struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev); |
| 930 | 930 | |
| 931 | − return sprintf(buf, "0x%04x\n", be16_to_cpu(dcr->code)); | |
| 931 | + return sprintf(buf, "0x%04x\n", le16_to_cpu(dcr->code)); | |
| 932 | 932 | } |
| 933 | 933 | static DEVICE_ATTR_RO(format); |
| 934 | 934 | |
| @@ -961,8 +961,8 @@ static ssize_t format1_show(struct device *dev, · 26 unmodified lines | ||
| 961 | 961 | continue; |
| 962 | 962 | if (nfit_dcr->dcr->code == dcr->code) |
| 963 | 963 | continue; |
| 964 | − rc = sprintf(buf, "%#x\n", | |
| 965 | − be16_to_cpu(nfit_dcr->dcr->code)); | |
| 964 | + rc = sprintf(buf, "0x%04x\n", | |
| 965 | + le16_to_cpu(nfit_dcr->dcr->code)); | |
| 966 | 966 | break; |
| 967 | 967 | } |
| 968 | 968 | if (rc != ENXIO) |
| @@ -1131,11 +1131,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, · 162 unmodified lines | ||
| 1131 | 1131 | |
| 1132 | 1132 | /* |
| 1133 | 1133 | * Until standardization materializes we need to consider up to 3 |
| 1134 | − * different command sets. Note, that checking for function0 (bit0) | |
| 1135 | − * tells us if any commands are reachable through this uuid. | |
| 1134 | + * different command sets. Note, that checking for zero functions | |
| 1135 | + * tells us if any commands might be reachable through this uuid. | |
| 1136 | 1136 | */ |
| 1137 | 1137 | for (i = NVDIMM_FAMILY_INTEL; i <= NVDIMM_FAMILY_HPE2; i++) |
| 1138 | − if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 1)) | |
| 1138 | + if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 0)) | |
| 1139 | 1139 | break; |
| 1140 | 1140 | |
| 1141 | 1141 | /* limit the supported commands to those that are publicly documented */ |
| @@ -53,12 +53,12 @@ enum nfit_uuids { · 52 unmodified lines | ||
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | 55 | /* |
| 56 | − * Region format interface codes are stored as an array of bytes in the | |
| 57 | − * NFIT DIMM Control Region structure | |
| 56 | + * Region format interface codes are stored with the interface as the | |
| 57 | + * LSB and the function as the MSB. | |
| 58 | 58 | */ |
| 59 | −#define NFIT_FIC_BYTE cpu_to_be16(0x101) /* byte-addressable energy backed */ | |
| 60 | −#define NFIT_FIC_BLK cpu_to_be16(0x201) /* block-addressable non-energy backed */ | |
| 61 | −#define NFIT_FIC_BYTEN cpu_to_be16(0x301) /* byte-addressable non-energy backed */ | |
| 59 | +#define NFIT_FIC_BYTE cpu_to_le16(0x101) /* byte-addressable energy backed */ | |
| 60 | +#define NFIT_FIC_BLK cpu_to_le16(0x201) /* block-addressable non-energy backed */ | |
| 61 | +#define NFIT_FIC_BYTEN cpu_to_le16(0x301) /* byte-addressable non-energy backed */ | |
| 62 | 62 | |
| 63 | 63 | enum { |
| 64 | 64 | NFIT_BLK_READ_FLUSH = 1, |
| @@ -680,9 +680,6 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs) · 679 unmodified lines | ||
| 680 | 680 | u64 mask = 0; |
| 681 | 681 | union acpi_object *obj; |
| 682 | 682 | |
| 683 | − if (funcs == 0) | |
| 684 | − return false; | |
| 685 | − | |
| 686 | 683 | obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL); |
| 687 | 684 | if (!obj) |
| 688 | 685 | return false; |
| @@ -695,6 +692,9 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs) · 6 unmodified lines | ||
| 695 | 692 | mask |= (((u64)obj->buffer.pointer[i]) << (i * 8)); |
| 696 | 693 | ACPI_FREE(obj); |
| 697 | 694 | |
| 695 | + if (funcs == 0) | |
| 696 | + return true; | |
| 697 | + | |
| 698 | 698 | /* |
| 699 | 699 | * Bit 0 indicates whether there's support for any functions other than |
| 700 | 700 | * function 0 for the specified UUID and revision. |
| @@ -344,6 +344,8 @@ struct device *nd_pfn_create(struct nd_region *nd_region) · 343 unmodified lines | ||
| 344 | 344 | int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) |
| 345 | 345 | { |
| 346 | 346 | u64 checksum, offset; |
| 347 | + unsigned long align; | |
| 348 | + enum nd_pfn_mode mode; | |
| 347 | 349 | struct nd_namespace_io *nsio; |
| 348 | 350 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; |
| 349 | 351 | struct nd_namespace_common *ndns = nd_pfn->ndns; |
| @@ -386,22 +388,50 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) · 36 unmodified lines | ||
| 386 | 388 | return -ENXIO; |
| 387 | 389 | } |
| 388 | 390 | |
| 391 | + align = le32_to_cpu(pfn_sb->align); | |
| 392 | + offset = le64_to_cpu(pfn_sb->dataoff); | |
| 393 | + if (align == 0) | |
| 394 | + align = 1UL << ilog2(offset); | |
| 395 | + mode = le32_to_cpu(pfn_sb->mode); | |
| 396 | + | |
| 389 | 397 | if (!nd_pfn->uuid) { |
| 390 | − /* from probe we allocate */ | |
| 398 | + /* | |
| 399 | + * When probing a namepace via nd_pfn_probe() the uuid | |
| 400 | + * is NULL (see: nd_pfn_devinit()) we init settings from | |
| 401 | + * pfn_sb | |
| 402 | + */ | |
| 391 | 403 | nd_pfn->uuid = kmemdup(pfn_sb->uuid, 16, GFP_KERNEL); |
| 392 | 404 | if (!nd_pfn->uuid) |
| 393 | 405 | return -ENOMEM; |
| 406 | + nd_pfn->align = align; | |
| 407 | + nd_pfn->mode = mode; | |
| 394 | 408 | } else { |
| 395 | − /* from init we validate */ | |
| 409 | + /* | |
| 410 | + * When probing a pfn / dax instance we validate the | |
| 411 | + * live settings against the pfn_sb | |
| 412 | + */ | |
| 396 | 413 | if (memcmp(nd_pfn->uuid, pfn_sb->uuid, 16) != 0) |
| 397 | 414 | return -ENODEV; |
| 415 | + | |
| 416 | + /* | |
| 417 | + * If the uuid validates, but other settings mismatch | |
| 418 | + * return EINVAL because userspace has managed to change | |
| 419 | + * the configuration without specifying new | |
| 420 | + * identification. | |
| 421 | + */ | |
| 422 | + if (nd_pfn->align != align || nd_pfn->mode != mode) { | |
| 423 | + dev_err(&nd_pfn->dev, | |
| 424 | + "init failed, settings mismatch\n"); | |
| 425 | + dev_dbg(&nd_pfn->dev, "align: %lx:%lx mode: %d:%d\n", | |
| 426 | + nd_pfn->align, align, nd_pfn->mode, | |
| 427 | + mode); | |
| 428 | + return -EINVAL; | |
| 429 | + } | |
| 398 | 430 | } |
| 399 | 431 | |
| 400 | − if (nd_pfn->align == 0) | |
| 401 | − nd_pfn->align = le32_to_cpu(pfn_sb->align); | |
| 402 | − if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) { | |
| 432 | + if (align > nvdimm_namespace_capacity(ndns)) { | |
| 403 | 433 | dev_err(&nd_pfn->dev, "alignment: %lx exceeds capacity %llx\n", |
| 404 | − nd_pfn->align, nvdimm_namespace_capacity(ndns)); | |
| 434 | + align, nvdimm_namespace_capacity(ndns)); | |
| 405 | 435 | return -EINVAL; |
| 406 | 436 | } |
| 407 | 437 | |
| @@ -411,7 +441,6 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) · 3 unmodified lines | ||
| 411 | 441 | * namespace has changed since the pfn superblock was |
| 412 | 442 | * established. |
| 413 | 443 | */ |
| 414 | − offset = le64_to_cpu(pfn_sb->dataoff); | |
| 415 | 444 | nsio = to_nd_namespace_io(&ndns->dev); |
| 416 | 445 | if (offset >= resource_size(&nsio->res)) { |
| 417 | 446 | dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n", |
| @@ -419,10 +448,11 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) · 1 unmodified line | ||
| 419 | 448 | return -EBUSY; |
| 420 | 449 | } |
| 421 | 450 | |
| 422 | − if ((nd_pfn->align && !IS_ALIGNED(offset, nd_pfn->align)) | |
| 451 | + if ((align && !IS_ALIGNED(offset, align)) | |
| 423 | 452 | || !IS_ALIGNED(offset, PAGE_SIZE)) { |
| 424 | − dev_err(&nd_pfn->dev, "bad offset: %#llx dax disabled\n", | |
| 425 | − offset); | |
| 453 | + dev_err(&nd_pfn->dev, | |
| 454 | + "bad offset: %#llx dax disabled align: %#lx\n", | |
| 455 | + offset, align); | |
| 426 | 456 | return -ENXIO; |
| 427 | 457 | } |
| 428 | 458 | |
| @@ -502,7 +532,6 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, · 73 unmodified lines | ||
| 502 | 532 | res->start += start_pad; |
| 503 | 533 | res->end -= end_trunc; |
| 504 | 534 | |
| 505 | − nd_pfn->mode = le32_to_cpu(nd_pfn->pfn_sb->mode); | |
| 506 | 535 | if (nd_pfn->mode == PFN_MODE_RAM) { |
| 507 | 536 | if (offset < SZ_8K) |
| 508 | 537 | return ERR_PTR(-EINVAL); |
| @@ -208,7 +208,12 @@ static ssize_t dax_io(struct inode *inode, struct iov_iter *iter, · 207 unmodified lines | ||
| 208 | 208 | dax.addr += first; |
| 209 | 209 | size = map_len - first; |
| 210 | 210 | } |
| 211 | − max = min(pos + size, end); | |
| 211 | + /* | |
| 212 | + * pos + size is one past the last offset for IO, | |
| 213 | + * so pos + size can overflow loff_t at extreme offsets. | |
| 214 | + * Cast to u64 to catch this and get the true minimum. | |
| 215 | + */ | |
| 216 | + max = min_t(u64, pos + size, end); | |
| 212 | 217 | } |
| 213 | 218 | |
| 214 | 219 | if (iov_iter_rw(iter) == WRITE) { |