--- /dev/null
+From 13e451fdc1af05568ea379d71c02a126295d2244 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 12 May 2017 15:46:57 -0700
+Subject: dax: fix data corruption when fault races with write
+
+From: Jan Kara <jack@suse.cz>
+
+commit 13e451fdc1af05568ea379d71c02a126295d2244 upstream.
+
+Currently DAX read fault can race with write(2) in the following way:
+
+CPU1 - write(2) CPU2 - read fault
+ dax_iomap_pte_fault()
+ ->iomap_begin() - sees hole
+dax_iomap_rw()
+ iomap_apply()
+ ->iomap_begin - allocates blocks
+ dax_iomap_actor()
+ invalidate_inode_pages2_range()
+ - there's nothing to invalidate
+ grab_mapping_entry()
+ - we add zero page in the radix tree
+ and map it to page tables
+
+The result is that hole page is mapped into page tables (and thus zeros
+are seen in mmap) while file has data written in that place.
+
+Fix the problem by locking exception entry before mapping blocks for the
+fault. That way we are sure invalidate_inode_pages2_range() call for
+racing write will either block on entry lock waiting for the fault to
+finish (and unmap stale page tables after that) or read fault will see
+already allocated blocks by write(2).
+
+Fixes: 9f141d6ef6258a3a37a045842d9ba7e68f368956
+Link: http://lkml.kernel.org/r/20170510085419.27601-5-jack@suse.cz
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
+Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dax.c | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+--- a/fs/dax.c
++++ b/fs/dax.c
+@@ -1124,23 +1124,23 @@ static int dax_iomap_pte_fault(struct vm
+ if ((vmf->flags & FAULT_FLAG_WRITE) && !vmf->cow_page)
+ flags |= IOMAP_WRITE;
+
++ entry = grab_mapping_entry(mapping, vmf->pgoff, 0);
++ if (IS_ERR(entry))
++ return dax_fault_return(PTR_ERR(entry));
++
+ /*
+ * Note that we don't bother to use iomap_apply here: DAX required
+ * the file system block size to be equal the page size, which means
+ * that we never have to deal with more than a single extent here.
+ */
+ error = ops->iomap_begin(inode, pos, PAGE_SIZE, flags, &iomap);
+- if (error)
+- return dax_fault_return(error);
+- if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) {
+- vmf_ret = dax_fault_return(-EIO); /* fs corruption? */
+- goto finish_iomap;
++ if (error) {
++ vmf_ret = dax_fault_return(error);
++ goto unlock_entry;
+ }
+-
+- entry = grab_mapping_entry(mapping, vmf->pgoff, 0);
+- if (IS_ERR(entry)) {
+- vmf_ret = dax_fault_return(PTR_ERR(entry));
+- goto finish_iomap;
++ if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) {
++ error = -EIO; /* fs corruption? */
++ goto error_finish_iomap;
+ }
+
+ sector = dax_iomap_sector(&iomap, pos);
+@@ -1162,13 +1162,13 @@ static int dax_iomap_pte_fault(struct vm
+ }
+
+ if (error)
+- goto error_unlock_entry;
++ goto error_finish_iomap;
+
+ __SetPageUptodate(vmf->cow_page);
+ vmf_ret = finish_fault(vmf);
+ if (!vmf_ret)
+ vmf_ret = VM_FAULT_DONE_COW;
+- goto unlock_entry;
++ goto finish_iomap;
+ }
+
+ switch (iomap.type) {
+@@ -1188,7 +1188,7 @@ static int dax_iomap_pte_fault(struct vm
+ case IOMAP_HOLE:
+ if (!(vmf->flags & FAULT_FLAG_WRITE)) {
+ vmf_ret = dax_load_hole(mapping, &entry, vmf);
+- goto unlock_entry;
++ goto finish_iomap;
+ }
+ /*FALLTHRU*/
+ default:
+@@ -1197,10 +1197,8 @@ static int dax_iomap_pte_fault(struct vm
+ break;
+ }
+
+- error_unlock_entry:
++ error_finish_iomap:
+ vmf_ret = dax_fault_return(error) | major;
+- unlock_entry:
+- put_locked_mapping_entry(mapping, vmf->pgoff, entry);
+ finish_iomap:
+ if (ops->iomap_end) {
+ int copied = PAGE_SIZE;
+@@ -1215,6 +1213,8 @@ static int dax_iomap_pte_fault(struct vm
+ */
+ ops->iomap_end(inode, pos, PAGE_SIZE, copied, flags, &iomap);
+ }
++ unlock_entry:
++ put_locked_mapping_entry(mapping, vmf->pgoff, entry);
+ return vmf_ret;
+ }
+
--- /dev/null
+From eb77e6b80f3bed262c7773236f0fb84649fd3091 Mon Sep 17 00:00:00 2001
+From: Yazen Ghannam <yazen.ghannam@amd.com>
+Date: Thu, 27 Apr 2017 12:11:54 -0500
+Subject: EDAC, amd64: Fix reporting of Chip Select sizes on Fam17h
+
+From: Yazen Ghannam <yazen.ghannam@amd.com>
+
+commit eb77e6b80f3bed262c7773236f0fb84649fd3091 upstream.
+
+The wrong index into the csbases/csmasks arrays was being passed to
+the function to compute the chip select sizes, which resulted in the
+wrong size being computed. Address that so that the correct values are
+computed and printed.
+
+Also, redo how we calculate the number of pages in a CS row.
+
+Reported-by: Benjamin Bennett <benbennett@gmail.com>
+Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
+Cc: linux-edac <linux-edac@vger.kernel.org>
+Link: http://lkml.kernel.org/r/1493313114-11260-1-git-send-email-Yazen.Ghannam@amd.com
+[ Remove unneeded integer math comment, minor cleanups. ]
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/edac/amd64_edac.c | 40 +++++++++++++++++++---------------------
+ 1 file changed, 19 insertions(+), 21 deletions(-)
+
+--- a/drivers/edac/amd64_edac.c
++++ b/drivers/edac/amd64_edac.c
+@@ -782,24 +782,26 @@ static void debug_dump_dramcfg_low(struc
+
+ static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
+ {
+- u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases;
+- int dimm, size0, size1;
++ int dimm, size0, size1, cs0, cs1;
+
+ edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl);
+
+ for (dimm = 0; dimm < 4; dimm++) {
+ size0 = 0;
++ cs0 = dimm * 2;
+
+- if (dcsb[dimm*2] & DCSB_CS_ENABLE)
+- size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm);
++ if (csrow_enabled(cs0, ctrl, pvt))
++ size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs0);
+
+ size1 = 0;
+- if (dcsb[dimm*2 + 1] & DCSB_CS_ENABLE)
+- size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm);
++ cs1 = dimm * 2 + 1;
++
++ if (csrow_enabled(cs1, ctrl, pvt))
++ size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1);
+
+ amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
+- dimm * 2, size0,
+- dimm * 2 + 1, size1);
++ cs0, size0,
++ cs1, size1);
+ }
+ }
+
+@@ -2756,26 +2758,22 @@ skip:
+ * encompasses
+ *
+ */
+-static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
++static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig)
+ {
+- u32 cs_mode, nr_pages;
+ u32 dbam = dct ? pvt->dbam1 : pvt->dbam0;
++ int csrow_nr = csrow_nr_orig;
++ u32 cs_mode, nr_pages;
+
++ if (!pvt->umc)
++ csrow_nr >>= 1;
+
+- /*
+- * The math on this doesn't look right on the surface because x/2*4 can
+- * be simplified to x*2 but this expression makes use of the fact that
+- * it is integral math where 1/2=0. This intermediate value becomes the
+- * number of bits to shift the DBAM register to extract the proper CSROW
+- * field.
+- */
+- cs_mode = DBAM_DIMM(csrow_nr / 2, dbam);
++ cs_mode = DBAM_DIMM(csrow_nr, dbam);
+
+- nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, (csrow_nr / 2))
+- << (20 - PAGE_SHIFT);
++ nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, csrow_nr);
++ nr_pages <<= 20 - PAGE_SHIFT;
+
+ edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n",
+- csrow_nr, dct, cs_mode);
++ csrow_nr_orig, dct, cs_mode);
+ edac_dbg(0, "nr_pages/channel: %u\n", nr_pages);
+
+ return nr_pages;
--- /dev/null
+From 8d13c0290655b883df9083a2a0af0d782bc38aef Mon Sep 17 00:00:00 2001
+From: Toshi Kani <toshi.kani@hpe.com>
+Date: Thu, 27 Apr 2017 16:57:05 -0600
+Subject: libnvdimm: fix clear length of nvdimm_forget_poison()
+
+From: Toshi Kani <toshi.kani@hpe.com>
+
+commit 8d13c0290655b883df9083a2a0af0d782bc38aef upstream.
+
+ND_CMD_CLEAR_ERROR command returns 'clear_err.cleared', the length
+of error actually cleared, which may be smaller than its requested
+'len'.
+
+Change nvdimm_clear_poison() to call nvdimm_forget_poison() with
+'clear_err.cleared' when this value is valid.
+
+Fixes: e046114af5fc ("libnvdimm: clear the internal poison_list when clearing badblocks")
+Cc: Dave Jiang <dave.jiang@intel.com>
+Cc: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/nvdimm/bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvdimm/bus.c
++++ b/drivers/nvdimm/bus.c
+@@ -218,7 +218,10 @@ long nvdimm_clear_poison(struct device *
+ if (cmd_rc < 0)
+ return cmd_rc;
+
+- nvdimm_clear_from_poison_list(nvdimm_bus, phys, len);
++ if (clear_err.cleared > 0)
++ nvdimm_clear_from_poison_list(nvdimm_bus, phys,
++ clear_err.cleared);
++
+ return clear_err.cleared;
+ }
+ EXPORT_SYMBOL_GPL(nvdimm_clear_poison);
usb-serial-ftdi_sio-add-olimex-arm-usb-tiny-h-pids.patch
usb-chaoskey-fix-alea-quirk-on-big-endian-hosts.patch
make-stat-lstat-fstatat-pass-at_no_automount-to-vfs_statx.patch
+libnvdimm-fix-clear-length-of-nvdimm_forget_poison.patch
+dax-fix-data-corruption-when-fault-races-with-write.patch
+edac-amd64-fix-reporting-of-chip-select-sizes-on-fam17h.patch