From: Greg Kroah-Hartman Date: Tue, 23 May 2017 18:38:03 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.55~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=13dcf9870688c0c879f4ab207e215b40aaa6e24c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: drivers-char-mem-check-for-address-space-wraparound-with-mmap.patch drm-edid-add-10-bpc-quirk-for-lgd-764-panel-in-hp-zbook-17-g2.patch drm-i915-gvt-disable-access-to-stolen-memory-as-a-guest.patch mtd-nand-add-ooblayout-for-old-hamming-layout.patch mtd-nand-omap2-fix-partition-creation-via-cmdline-mtdparts.patch mtd-nand-orion-fix-clk-handling.patch nfs-fix-use-after-free-in-write-error-path.patch nfs-use-gfp_noio-for-two-allocations-in-writeback.patch nfsd-check-for-oversized-nfsv2-v3-arguments.patch nfsd-encoders-mustn-t-use-unitialized-values-in-error-cases.patch nfsd-fix-undefined-behavior-in-nfsd4_layout_verify.patch nfsd-fix-up-the-supattr_exclcreat-attributes.patch nfsv4-fix-a-hang-in-open-related-to-server-reboot.patch osf_wait4-fix-infoleak.patch pci-fix-another-sanity-check-bug-in-proc-pci-mmap.patch pci-fix-pci_mmap_fits-for-have_pci_resource_to_user-platforms.patch pci-freeze-pme-scan-before-suspending-devices.patch pci-hv-allocate-interrupt-descriptors-with-gfp_atomic.patch pci-hv-specify-cpu_affinity_all-for-msi-affinity-when-32-cpus.patch pci-only-allow-wc-mmap-on-prefetchable-resources.patch tracing-kprobes-enforce-kprobes-teardown-after-testing.patch um-fix-to-call-read_initrd-after-init_bootmem.patch --- diff --git a/queue-4.9/drivers-char-mem-check-for-address-space-wraparound-with-mmap.patch b/queue-4.9/drivers-char-mem-check-for-address-space-wraparound-with-mmap.patch new file mode 100644 index 00000000000..e2e7c675f8d --- /dev/null +++ b/queue-4.9/drivers-char-mem-check-for-address-space-wraparound-with-mmap.patch @@ -0,0 +1,40 @@ +From b299cde245b0b76c977f4291162cf668e087b408 Mon Sep 17 00:00:00 2001 +From: Julius Werner +Date: Fri, 12 May 2017 14:42:58 -0700 +Subject: drivers: char: mem: Check for address space wraparound with mmap() + +From: Julius Werner + +commit b299cde245b0b76c977f4291162cf668e087b408 upstream. + +/dev/mem currently allows mmap() mappings that wrap around the end of +the physical address space, which should probably be illegal. It +circumvents the existing STRICT_DEVMEM permission check because the loop +immediately terminates (as the start address is already higher than the +end address). On the x86_64 architecture it will then cause a panic +(from the BUG(start >= end) in arch/x86/mm/pat.c:reserve_memtype()). + +This patch adds an explicit check to make sure offset + size will not +wrap around in the physical address type. + +Signed-off-by: Julius Werner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/mem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/char/mem.c ++++ b/drivers/char/mem.c +@@ -340,6 +340,11 @@ static const struct vm_operations_struct + static int mmap_mem(struct file *file, struct vm_area_struct *vma) + { + size_t size = vma->vm_end - vma->vm_start; ++ phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; ++ ++ /* It's illegal to wrap around the end of the physical address space. */ ++ if (offset + (phys_addr_t)size < offset) ++ return -EINVAL; + + if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) + return -EINVAL; diff --git a/queue-4.9/drm-edid-add-10-bpc-quirk-for-lgd-764-panel-in-hp-zbook-17-g2.patch b/queue-4.9/drm-edid-add-10-bpc-quirk-for-lgd-764-panel-in-hp-zbook-17-g2.patch new file mode 100644 index 00000000000..c701d098b65 --- /dev/null +++ b/queue-4.9/drm-edid-add-10-bpc-quirk-for-lgd-764-panel-in-hp-zbook-17-g2.patch @@ -0,0 +1,57 @@ +From e345da82bd6bdfa8492f80b3ce4370acfd868d95 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Fri, 21 Apr 2017 17:05:08 +0200 +Subject: drm/edid: Add 10 bpc quirk for LGD 764 panel in HP zBook 17 G2 + +From: Mario Kleiner + +commit e345da82bd6bdfa8492f80b3ce4370acfd868d95 upstream. + +The builtin eDP panel in the HP zBook 17 G2 supports 10 bpc, +as advertised by the Laptops product specs and verified via +injecting a fixed edid + photometer measurements, but edid +reports unknown depth, so drivers fall back to 6 bpc. + +Add a quirk to get the full 10 bpc. + +Signed-off-by: Mario Kleiner +Acked-by: Harry Wentland +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/1492787108-23959-1-git-send-email-mario.kleiner.de@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_edid.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -76,6 +76,8 @@ + #define EDID_QUIRK_FORCE_12BPC (1 << 9) + /* Force 6bpc */ + #define EDID_QUIRK_FORCE_6BPC (1 << 10) ++/* Force 10bpc */ ++#define EDID_QUIRK_FORCE_10BPC (1 << 11) + + struct detailed_mode_closure { + struct drm_connector *connector; +@@ -118,6 +120,9 @@ static const struct edid_quirk { + { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | + EDID_QUIRK_DETAILED_IN_CM }, + ++ /* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */ ++ { "LGD", 764, EDID_QUIRK_FORCE_10BPC }, ++ + /* LG Philips LCD LP154W01-A5 */ + { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, + { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, +@@ -4105,6 +4110,9 @@ int drm_add_edid_modes(struct drm_connec + if (quirks & EDID_QUIRK_FORCE_8BPC) + connector->display_info.bpc = 8; + ++ if (quirks & EDID_QUIRK_FORCE_10BPC) ++ connector->display_info.bpc = 10; ++ + if (quirks & EDID_QUIRK_FORCE_12BPC) + connector->display_info.bpc = 12; + diff --git a/queue-4.9/drm-i915-gvt-disable-access-to-stolen-memory-as-a-guest.patch b/queue-4.9/drm-i915-gvt-disable-access-to-stolen-memory-as-a-guest.patch new file mode 100644 index 00000000000..46ea7dcc1de --- /dev/null +++ b/queue-4.9/drm-i915-gvt-disable-access-to-stolen-memory-as-a-guest.patch @@ -0,0 +1,40 @@ +From 04a68a35ce6d7b54749989f943993020f48fed62 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 9 Nov 2016 10:39:05 +0000 +Subject: drm/i915/gvt: Disable access to stolen memory as a guest + +From: Chris Wilson + +commit 04a68a35ce6d7b54749989f943993020f48fed62 upstream. + +Explicitly disable stolen memory when running as a guest in a virtual +machine, since the memory is not mediated between clients and reserved +entirely for the host. The actual size should be reported as zero, but +like every other quirk we want to tell the user what is happening. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99028 +Signed-off-by: Chris Wilson +Cc: Zhenyu Wang +Cc: Joonas Lahtinen +Link: http://patchwork.freedesktop.org/patch/msgid/20161109103905.17860-1-chris@chris-wilson.co.uk +Reviewed-by: Zhenyu Wang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -420,6 +420,11 @@ int i915_gem_init_stolen(struct drm_devi + return 0; + } + ++ if (intel_vgpu_active(dev_priv)) { ++ DRM_INFO("iGVT-g active, disabling use of stolen memory\n"); ++ return 0; ++ } ++ + #ifdef CONFIG_INTEL_IOMMU + if (intel_iommu_gfx_mapped && INTEL_INFO(dev)->gen < 8) { + DRM_INFO("DMAR active, disabling use of stolen memory\n"); diff --git a/queue-4.9/mtd-nand-add-ooblayout-for-old-hamming-layout.patch b/queue-4.9/mtd-nand-add-ooblayout-for-old-hamming-layout.patch new file mode 100644 index 00000000000..c2dfd261abf --- /dev/null +++ b/queue-4.9/mtd-nand-add-ooblayout-for-old-hamming-layout.patch @@ -0,0 +1,109 @@ +From 6a623e07694437ad09f382a13f76cffc32239a7f Mon Sep 17 00:00:00 2001 +From: Alexander Couzens +Date: Tue, 2 May 2017 12:19:00 +0200 +Subject: mtd: nand: add ooblayout for old hamming layout + +From: Alexander Couzens + +commit 6a623e07694437ad09f382a13f76cffc32239a7f upstream. + +The old 1-bit hamming layout requires ECC data to be placed at a +fixed offset, and not necessarily at the end of the OOB area. +Add this old layout back in order to fix legacy setups. + +Fixes: 41b207a70d3a ("mtd: nand: implement the default mtd_ooblayout_ops") +Signed-off-by: Alexander Couzens +Acked-by: Boris Brezillon +Signed-off-by: Brian Norris +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/nand_base.c | 70 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 69 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/nand_base.c ++++ b/drivers/mtd/nand/nand_base.c +@@ -138,6 +138,74 @@ const struct mtd_ooblayout_ops nand_oobl + }; + EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops); + ++/* ++ * Support the old "large page" layout used for 1-bit Hamming ECC where ECC ++ * are placed at a fixed offset. ++ */ ++static int nand_ooblayout_ecc_lp_hamming(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ ++ if (section) ++ return -ERANGE; ++ ++ switch (mtd->oobsize) { ++ case 64: ++ oobregion->offset = 40; ++ break; ++ case 128: ++ oobregion->offset = 80; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ oobregion->length = ecc->total; ++ if (oobregion->offset + oobregion->length > mtd->oobsize) ++ return -ERANGE; ++ ++ return 0; ++} ++ ++static int nand_ooblayout_free_lp_hamming(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ int ecc_offset = 0; ++ ++ if (section < 0 || section > 1) ++ return -ERANGE; ++ ++ switch (mtd->oobsize) { ++ case 64: ++ ecc_offset = 40; ++ break; ++ case 128: ++ ecc_offset = 80; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (section == 0) { ++ oobregion->offset = 2; ++ oobregion->length = ecc_offset - 2; ++ } else { ++ oobregion->offset = ecc_offset + ecc->total; ++ oobregion->length = mtd->oobsize - oobregion->offset; ++ } ++ ++ return 0; ++} ++ ++const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { ++ .ecc = nand_ooblayout_ecc_lp_hamming, ++ .free = nand_ooblayout_free_lp_hamming, ++}; ++ + static int check_offs_len(struct mtd_info *mtd, + loff_t ofs, uint64_t len) + { +@@ -4565,7 +4633,7 @@ int nand_scan_tail(struct mtd_info *mtd) + break; + case 64: + case 128: +- mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); ++ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_hamming_ops); + break; + default: + WARN(1, "No oob scheme defined for oobsize %d\n", diff --git a/queue-4.9/mtd-nand-omap2-fix-partition-creation-via-cmdline-mtdparts.patch b/queue-4.9/mtd-nand-omap2-fix-partition-creation-via-cmdline-mtdparts.patch new file mode 100644 index 00000000000..d6a88d681d2 --- /dev/null +++ b/queue-4.9/mtd-nand-omap2-fix-partition-creation-via-cmdline-mtdparts.patch @@ -0,0 +1,51 @@ +From 2d283ede59869159f4bb84ae689258c5caffce54 Mon Sep 17 00:00:00 2001 +From: Roger Quadros +Date: Thu, 30 Mar 2017 10:37:50 +0300 +Subject: mtd: nand: omap2: Fix partition creation via cmdline mtdparts + +From: Roger Quadros + +commit 2d283ede59869159f4bb84ae689258c5caffce54 upstream. + +commit c9711ec5250b ("mtd: nand: omap: Clean up device tree support") +caused the parent device name to be changed from "omap2-nand.0" +to ".nand" (e.g. 30000000.nand on omap3 platforms). +This caused mtd->name to be changed as well. This breaks partition +creation via mtdparts passed by u-boot as it uses "omap2-nand.0" +for the mtd-id. + +Fix this by explicitly setting the mtd->name to "omap2-nand." +if it isn't already set by nand_set_flash_node(). CS number is the +NAND controller instance ID. + +Fixes: c9711ec5250b ("mtd: nand: omap: Clean up device tree support") +Reported-by: Leto Enrico +Reported-by: Adam Ford +Suggested-by: Boris Brezillon +Tested-by: Adam Ford +Signed-off-by: Roger Quadros +Signed-off-by: Boris Brezillon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/omap2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/mtd/nand/omap2.c ++++ b/drivers/mtd/nand/omap2.c +@@ -1856,6 +1856,15 @@ static int omap_nand_probe(struct platfo + nand_chip->ecc.priv = NULL; + nand_set_flash_node(nand_chip, dev->of_node); + ++ if (!mtd->name) { ++ mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, ++ "omap2-nand.%d", info->gpmc_cs); ++ if (!mtd->name) { ++ dev_err(&pdev->dev, "Failed to set MTD name\n"); ++ return -ENOMEM; ++ } ++ } ++ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(nand_chip->IO_ADDR_R)) diff --git a/queue-4.9/mtd-nand-orion-fix-clk-handling.patch b/queue-4.9/mtd-nand-orion-fix-clk-handling.patch new file mode 100644 index 00000000000..cf3d6f59ed2 --- /dev/null +++ b/queue-4.9/mtd-nand-orion-fix-clk-handling.patch @@ -0,0 +1,124 @@ +From 675b11d94ce9baa5eb365a51b35d2793f77c8ab8 Mon Sep 17 00:00:00 2001 +From: Simon Baatz +Date: Mon, 27 Mar 2017 20:02:07 +0200 +Subject: mtd: nand: orion: fix clk handling + +From: Simon Baatz + +commit 675b11d94ce9baa5eb365a51b35d2793f77c8ab8 upstream. + +The clk handling in orion_nand.c had two problems: + +- In the probe function, clk_put() was called for an enabled clock, + which violates the API (see documentation for clk_put() in + include/linux/clk.h) + +- In the error path of the probe function, clk_put() could be called + twice for the same clock. + +In order to clean this up, use the managed function devm_clk_get() and +store the pointer to the clk in the driver data. + +Fixes: baffab28b13120694fa3ebab08d3e99667a851d2 ('ARM: Orion: fix driver probe error handling with respect to clk') +Signed-off-by: Simon Baatz +Signed-off-by: Boris Brezillon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/orion_nand.c | 42 +++++++++++++++++++++--------------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +--- a/drivers/mtd/nand/orion_nand.c ++++ b/drivers/mtd/nand/orion_nand.c +@@ -23,6 +23,11 @@ + #include + #include + ++struct orion_nand_info { ++ struct nand_chip chip; ++ struct clk *clk; ++}; ++ + static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) + { + struct nand_chip *nc = mtd_to_nand(mtd); +@@ -75,20 +80,21 @@ static void orion_nand_read_buf(struct m + + static int __init orion_nand_probe(struct platform_device *pdev) + { ++ struct orion_nand_info *info; + struct mtd_info *mtd; + struct nand_chip *nc; + struct orion_nand_data *board; + struct resource *res; +- struct clk *clk; + void __iomem *io_base; + int ret = 0; + u32 val = 0; + +- nc = devm_kzalloc(&pdev->dev, +- sizeof(struct nand_chip), ++ info = devm_kzalloc(&pdev->dev, ++ sizeof(struct orion_nand_info), + GFP_KERNEL); +- if (!nc) ++ if (!info) + return -ENOMEM; ++ nc = &info->chip; + mtd = nand_to_mtd(nc); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -145,15 +151,13 @@ static int __init orion_nand_probe(struc + if (board->dev_ready) + nc->dev_ready = board->dev_ready; + +- platform_set_drvdata(pdev, mtd); ++ platform_set_drvdata(pdev, info); + + /* Not all platforms can gate the clock, so it is not + an error if the clock does not exists. */ +- clk = clk_get(&pdev->dev, NULL); +- if (!IS_ERR(clk)) { +- clk_prepare_enable(clk); +- clk_put(clk); +- } ++ info->clk = devm_clk_get(&pdev->dev, NULL); ++ if (!IS_ERR(info->clk)) ++ clk_prepare_enable(info->clk); + + if (nand_scan(mtd, 1)) { + ret = -ENXIO; +@@ -170,26 +174,22 @@ static int __init orion_nand_probe(struc + return 0; + + no_dev: +- if (!IS_ERR(clk)) { +- clk_disable_unprepare(clk); +- clk_put(clk); +- } ++ if (!IS_ERR(info->clk)) ++ clk_disable_unprepare(info->clk); + + return ret; + } + + static int orion_nand_remove(struct platform_device *pdev) + { +- struct mtd_info *mtd = platform_get_drvdata(pdev); +- struct clk *clk; ++ struct orion_nand_info *info = platform_get_drvdata(pdev); ++ struct nand_chip *chip = &info->chip; ++ struct mtd_info *mtd = nand_to_mtd(chip); + + nand_release(mtd); + +- clk = clk_get(&pdev->dev, NULL); +- if (!IS_ERR(clk)) { +- clk_disable_unprepare(clk); +- clk_put(clk); +- } ++ if (!IS_ERR(info->clk)) ++ clk_disable_unprepare(info->clk); + + return 0; + } diff --git a/queue-4.9/nfs-fix-use-after-free-in-write-error-path.patch b/queue-4.9/nfs-fix-use-after-free-in-write-error-path.patch new file mode 100644 index 00000000000..b3602727838 --- /dev/null +++ b/queue-4.9/nfs-fix-use-after-free-in-write-error-path.patch @@ -0,0 +1,31 @@ +From 1f84ccdf37d0db3a70714d02d51b0b6d45887fb8 Mon Sep 17 00:00:00 2001 +From: Fred Isaman +Date: Fri, 14 Apr 2017 14:24:28 -0400 +Subject: NFS: Fix use after free in write error path + +From: Fred Isaman + +commit 1f84ccdf37d0db3a70714d02d51b0b6d45887fb8 upstream. + +Signed-off-by: Fred Isaman +Fixes: 0bcbf039f6b2b ("nfs: handle request add failure properly") +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/write.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -548,9 +548,9 @@ static void nfs_write_error_remove_page( + { + nfs_unlock_request(req); + nfs_end_page_writeback(req); +- nfs_release_request(req); + generic_error_remove_page(page_file_mapping(req->wb_page), + req->wb_page); ++ nfs_release_request(req); + } + + /* diff --git a/queue-4.9/nfs-use-gfp_noio-for-two-allocations-in-writeback.patch b/queue-4.9/nfs-use-gfp_noio-for-two-allocations-in-writeback.patch new file mode 100644 index 00000000000..3d62359494e --- /dev/null +++ b/queue-4.9/nfs-use-gfp_noio-for-two-allocations-in-writeback.patch @@ -0,0 +1,74 @@ +From ae97aa524ef495b6276fd26f5d5449fb22975d7c Mon Sep 17 00:00:00 2001 +From: Benjamin Coddington +Date: Wed, 19 Apr 2017 10:11:33 -0400 +Subject: NFS: Use GFP_NOIO for two allocations in writeback + +From: Benjamin Coddington + +commit ae97aa524ef495b6276fd26f5d5449fb22975d7c upstream. + +Prevent a deadlock that can occur if we wait on allocations +that try to write back our pages. + +Signed-off-by: Benjamin Coddington +Fixes: 00bfa30abe869 ("NFS: Create a common pgio_alloc and pgio_release...") +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/pagelist.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/fs/nfs/pagelist.c ++++ b/fs/nfs/pagelist.c +@@ -29,13 +29,14 @@ + static struct kmem_cache *nfs_page_cachep; + static const struct rpc_call_ops nfs_pgio_common_ops; + +-static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount) ++static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount, ++ gfp_t gfp_flags) + { + p->npages = pagecount; + if (pagecount <= ARRAY_SIZE(p->page_array)) + p->pagevec = p->page_array; + else { +- p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL); ++ p->pagevec = kcalloc(pagecount, sizeof(struct page *), gfp_flags); + if (!p->pagevec) + p->npages = 0; + } +@@ -681,6 +682,7 @@ void nfs_pageio_init(struct nfs_pageio_d + { + struct nfs_pgio_mirror *new; + int i; ++ gfp_t gfp_flags = GFP_KERNEL; + + desc->pg_moreio = 0; + desc->pg_inode = inode; +@@ -700,8 +702,10 @@ void nfs_pageio_init(struct nfs_pageio_d + if (pg_ops->pg_get_mirror_count) { + /* until we have a request, we don't have an lseg and no + * idea how many mirrors there will be */ ++ if (desc->pg_rw_ops->rw_mode == FMODE_WRITE) ++ gfp_flags = GFP_NOIO; + new = kcalloc(NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX, +- sizeof(struct nfs_pgio_mirror), GFP_KERNEL); ++ sizeof(struct nfs_pgio_mirror), gfp_flags); + desc->pg_mirrors_dynamic = new; + desc->pg_mirrors = new; + +@@ -755,9 +759,12 @@ int nfs_generic_pgio(struct nfs_pageio_d + struct list_head *head = &mirror->pg_list; + struct nfs_commit_info cinfo; + unsigned int pagecount, pageused; ++ gfp_t gfp_flags = GFP_KERNEL; + + pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count); +- if (!nfs_pgarray_set(&hdr->page_array, pagecount)) { ++ if (desc->pg_rw_ops->rw_mode == FMODE_WRITE) ++ gfp_flags = GFP_NOIO; ++ if (!nfs_pgarray_set(&hdr->page_array, pagecount, gfp_flags)) { + nfs_pgio_error(hdr); + desc->pg_error = -ENOMEM; + return desc->pg_error; diff --git a/queue-4.9/nfsd-check-for-oversized-nfsv2-v3-arguments.patch b/queue-4.9/nfsd-check-for-oversized-nfsv2-v3-arguments.patch new file mode 100644 index 00000000000..8f2b32d802d --- /dev/null +++ b/queue-4.9/nfsd-check-for-oversized-nfsv2-v3-arguments.patch @@ -0,0 +1,176 @@ +From 51f567777799c9d85a778302b9eb61cf15214a98 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Thu, 6 Apr 2017 22:36:31 -0400 +Subject: nfsd: check for oversized NFSv2/v3 arguments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: J. Bruce Fields + +commit 51f567777799c9d85a778302b9eb61cf15214a98 upstream. + +A client can append random data to the end of an NFSv2 or NFSv3 RPC call +without our complaining; we'll just stop parsing at the end of the +expected data and ignore the rest. + +Encoded arguments and replies are stored together in an array of pages, +and if a call is too large it could leave inadequate space for the +reply. This is normally OK because NFS RPC's typically have either +short arguments and long replies (like READ) or long arguments and short +replies (like WRITE). But a client that sends an incorrectly long reply +can violate those assumptions. This was observed to cause crashes. + +So, insist that the argument not be any longer than we expect. + +Also, several operations increment rq_next_page in the decode routine +before checking the argument size, which can leave rq_next_page pointing +well past the end of the page array, causing trouble later in +svc_free_pages. + +As followup we may also want to rewrite the encoding routines to check +more carefully that they aren't running off the end of the page array. + +Reported-by: Tuomas Haanpää +Reported-by: Ari Kauppi +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs3xdr.c | 23 +++++++++++++++++------ + fs/nfsd/nfsxdr.c | 13 ++++++++++--- + include/linux/sunrpc/svc.h | 3 +-- + 3 files changed, 28 insertions(+), 11 deletions(-) + +--- a/fs/nfsd/nfs3xdr.c ++++ b/fs/nfsd/nfs3xdr.c +@@ -334,8 +334,11 @@ nfs3svc_decode_readargs(struct svc_rqst + if (!p) + return 0; + p = xdr_decode_hyper(p, &args->offset); +- + args->count = ntohl(*p++); ++ ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + len = min(args->count, max_blocksize); + + /* set up the kvec */ +@@ -349,7 +352,7 @@ nfs3svc_decode_readargs(struct svc_rqst + v++; + } + args->vlen = v; +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -541,9 +544,11 @@ nfs3svc_decode_readlinkargs(struct svc_r + p = decode_fh(p, &args->fh); + if (!p) + return 0; ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -569,10 +574,14 @@ nfs3svc_decode_readdirargs(struct svc_rq + args->verf = p; p += 2; + args->dircount = ~0; + args->count = ntohl(*p++); ++ ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + args->count = min_t(u32, args->count, PAGE_SIZE); + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -590,6 +599,9 @@ nfs3svc_decode_readdirplusargs(struct sv + args->dircount = ntohl(*p++); + args->count = ntohl(*p++); + ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + len = args->count = min(args->count, max_blocksize); + while (len > 0) { + struct page *p = *(rqstp->rq_next_page++); +@@ -597,8 +609,7 @@ nfs3svc_decode_readdirplusargs(struct sv + args->buffer = page_address(p); + len -= PAGE_SIZE; + } +- +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +--- a/fs/nfsd/nfsxdr.c ++++ b/fs/nfsd/nfsxdr.c +@@ -257,6 +257,9 @@ nfssvc_decode_readargs(struct svc_rqst * + len = args->count = ntohl(*p++); + p++; /* totalcount - unused */ + ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; ++ + len = min_t(unsigned int, len, NFSSVC_MAXBLKSIZE_V2); + + /* set up somewhere to store response. +@@ -272,7 +275,7 @@ nfssvc_decode_readargs(struct svc_rqst * + v++; + } + args->vlen = v; +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -362,9 +365,11 @@ nfssvc_decode_readlinkargs(struct svc_rq + p = decode_fh(p, &args->fh); + if (!p) + return 0; ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + int +@@ -402,9 +407,11 @@ nfssvc_decode_readdirargs(struct svc_rqs + args->cookie = ntohl(*p++); + args->count = ntohl(*p++); + args->count = min_t(u32, args->count, PAGE_SIZE); ++ if (!xdr_argsize_check(rqstp, p)) ++ return 0; + args->buffer = page_address(*(rqstp->rq_next_page++)); + +- return xdr_argsize_check(rqstp, p); ++ return 1; + } + + /* +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -336,8 +336,7 @@ xdr_argsize_check(struct svc_rqst *rqstp + { + char *cp = (char *)p; + struct kvec *vec = &rqstp->rq_arg.head[0]; +- return cp >= (char*)vec->iov_base +- && cp <= (char*)vec->iov_base + vec->iov_len; ++ return cp == (char *)vec->iov_base + vec->iov_len; + } + + static inline int diff --git a/queue-4.9/nfsd-encoders-mustn-t-use-unitialized-values-in-error-cases.patch b/queue-4.9/nfsd-encoders-mustn-t-use-unitialized-values-in-error-cases.patch new file mode 100644 index 00000000000..6182cffa347 --- /dev/null +++ b/queue-4.9/nfsd-encoders-mustn-t-use-unitialized-values-in-error-cases.patch @@ -0,0 +1,64 @@ +From f961e3f2acae94b727380c0b74e2d3954d0edf79 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Fri, 5 May 2017 16:17:57 -0400 +Subject: nfsd: encoders mustn't use unitialized values in error cases + +From: J. Bruce Fields + +commit f961e3f2acae94b727380c0b74e2d3954d0edf79 upstream. + +In error cases, lgp->lg_layout_type may be out of bounds; so we +shouldn't be using it until after the check of nfserr. + +This was seen to crash nfsd threads when the server receives a LAYOUTGET +request with a large layout type. + +GETDEVICEINFO has the same problem. + +Reported-by: Ari Kauppi +Reviewed-by: Christoph Hellwig +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4xdr.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -4081,8 +4081,7 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_ + struct nfsd4_getdeviceinfo *gdev) + { + struct xdr_stream *xdr = &resp->xdr; +- const struct nfsd4_layout_ops *ops = +- nfsd4_layout_ops[gdev->gd_layout_type]; ++ const struct nfsd4_layout_ops *ops; + u32 starting_len = xdr->buf->len, needed_len; + __be32 *p; + +@@ -4099,6 +4098,7 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_ + + /* If maxcount is 0 then just update notifications */ + if (gdev->gd_maxcount != 0) { ++ ops = nfsd4_layout_ops[gdev->gd_layout_type]; + nfserr = ops->encode_getdeviceinfo(xdr, gdev); + if (nfserr) { + /* +@@ -4151,8 +4151,7 @@ nfsd4_encode_layoutget(struct nfsd4_comp + struct nfsd4_layoutget *lgp) + { + struct xdr_stream *xdr = &resp->xdr; +- const struct nfsd4_layout_ops *ops = +- nfsd4_layout_ops[lgp->lg_layout_type]; ++ const struct nfsd4_layout_ops *ops; + __be32 *p; + + dprintk("%s: err %d\n", __func__, nfserr); +@@ -4175,6 +4174,7 @@ nfsd4_encode_layoutget(struct nfsd4_comp + *p++ = cpu_to_be32(lgp->lg_seg.iomode); + *p++ = cpu_to_be32(lgp->lg_layout_type); + ++ ops = nfsd4_layout_ops[lgp->lg_layout_type]; + nfserr = ops->encode_layoutget(xdr, lgp); + out: + kfree(lgp->lg_content); diff --git a/queue-4.9/nfsd-fix-undefined-behavior-in-nfsd4_layout_verify.patch b/queue-4.9/nfsd-fix-undefined-behavior-in-nfsd4_layout_verify.patch new file mode 100644 index 00000000000..21f03b0985d --- /dev/null +++ b/queue-4.9/nfsd-fix-undefined-behavior-in-nfsd4_layout_verify.patch @@ -0,0 +1,41 @@ +From b550a32e60a4941994b437a8d662432a486235a5 Mon Sep 17 00:00:00 2001 +From: Ari Kauppi +Date: Fri, 5 May 2017 16:07:55 -0400 +Subject: nfsd: fix undefined behavior in nfsd4_layout_verify + +From: Ari Kauppi + +commit b550a32e60a4941994b437a8d662432a486235a5 upstream. + + UBSAN: Undefined behaviour in fs/nfsd/nfs4proc.c:1262:34 + shift exponent 128 is too large for 32-bit type 'int' + +Depending on compiler+architecture, this may cause the check for +layout_type to succeed for overly large values (which seems to be the +case with amd64). The large value will be later used in de-referencing +nfsd4_layout_ops for function pointers. + +Reported-by: Jani Tuovila +Signed-off-by: Ari Kauppi +[colin.king@canonical.com: use LAYOUT_TYPE_MAX instead of 32] +Reviewed-by: Dan Carpenter +Reviewed-by: Christoph Hellwig +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4proc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1273,7 +1273,8 @@ nfsd4_layout_verify(struct svc_export *e + return NULL; + } + +- if (!(exp->ex_layout_types & (1 << layout_type))) { ++ if (layout_type >= LAYOUT_TYPE_MAX || ++ !(exp->ex_layout_types & (1 << layout_type))) { + dprintk("%s: layout type %d not supported\n", + __func__, layout_type); + return NULL; diff --git a/queue-4.9/nfsd-fix-up-the-supattr_exclcreat-attributes.patch b/queue-4.9/nfsd-fix-up-the-supattr_exclcreat-attributes.patch new file mode 100644 index 00000000000..40817da7072 --- /dev/null +++ b/queue-4.9/nfsd-fix-up-the-supattr_exclcreat-attributes.patch @@ -0,0 +1,41 @@ +From b26b78cb726007533d81fdf90a62e915002ef5c8 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Tue, 9 May 2017 16:24:59 -0400 +Subject: nfsd: Fix up the "supattr_exclcreat" attributes + +From: Trond Myklebust + +commit b26b78cb726007533d81fdf90a62e915002ef5c8 upstream. + +If an NFSv4 client asks us for the supattr_exclcreat, then we must +not return attributes that are unsupported by this minor version. + +Signed-off-by: Trond Myklebust +Fixes: 75976de6556f ("NFSD: Return word2 bitmask if setting security..,") +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4xdr.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -2793,9 +2793,14 @@ out_acl: + } + #endif /* CONFIG_NFSD_PNFS */ + if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { +- status = nfsd4_encode_bitmap(xdr, NFSD_SUPPATTR_EXCLCREAT_WORD0, +- NFSD_SUPPATTR_EXCLCREAT_WORD1, +- NFSD_SUPPATTR_EXCLCREAT_WORD2); ++ u32 supp[3]; ++ ++ memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp)); ++ supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0; ++ supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1; ++ supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2; ++ ++ status = nfsd4_encode_bitmap(xdr, supp[0], supp[1], supp[2]); + if (status) + goto out; + } diff --git a/queue-4.9/nfsv4-fix-a-hang-in-open-related-to-server-reboot.patch b/queue-4.9/nfsv4-fix-a-hang-in-open-related-to-server-reboot.patch new file mode 100644 index 00000000000..33e712883f1 --- /dev/null +++ b/queue-4.9/nfsv4-fix-a-hang-in-open-related-to-server-reboot.patch @@ -0,0 +1,37 @@ +From 56e0d71ef12f026d96213e45a662bde6bbff4676 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sat, 15 Apr 2017 19:20:01 -0400 +Subject: NFSv4: Fix a hang in OPEN related to server reboot + +From: Trond Myklebust + +commit 56e0d71ef12f026d96213e45a662bde6bbff4676 upstream. + +If the server fails to return the attributes as part of an OPEN +reply, and then reboots, we can end up hanging. The reason is that +the client attempts to send a GETATTR in order to pick up the +missing OPEN call, but fails to release the slot first, causing +reboot recovery to deadlock. + +Signed-off-by: Trond Myklebust +Fixes: 2e80dbe7ac51a ("NFSv4.1: Close callback races for OPEN, LAYOUTGET...") +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -2385,8 +2385,10 @@ static int _nfs4_proc_open(struct nfs4_o + if (status != 0) + return status; + } +- if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) ++ if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) { ++ nfs4_sequence_free_slot(&o_res->seq_res); + nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, o_res->f_label); ++ } + return 0; + } + diff --git a/queue-4.9/osf_wait4-fix-infoleak.patch b/queue-4.9/osf_wait4-fix-infoleak.patch new file mode 100644 index 00000000000..7c4742f3ba8 --- /dev/null +++ b/queue-4.9/osf_wait4-fix-infoleak.patch @@ -0,0 +1,33 @@ +From a8c39544a6eb2093c04afd5005b6192bd0e880c6 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 14 May 2017 21:47:25 -0400 +Subject: osf_wait4(): fix infoleak + +From: Al Viro + +commit a8c39544a6eb2093c04afd5005b6192bd0e880c6 upstream. + +failing sys_wait4() won't fill struct rusage... + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + arch/alpha/kernel/osf_sys.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/alpha/kernel/osf_sys.c ++++ b/arch/alpha/kernel/osf_sys.c +@@ -1188,8 +1188,10 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, i + if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur))) + return -EFAULT; + +- err = 0; +- err |= put_user(status, ustatus); ++ err = put_user(status, ustatus); ++ if (ret < 0) ++ return err ? err : ret; ++ + err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec); + err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec); + err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec); diff --git a/queue-4.9/pci-fix-another-sanity-check-bug-in-proc-pci-mmap.patch b/queue-4.9/pci-fix-another-sanity-check-bug-in-proc-pci-mmap.patch new file mode 100644 index 00000000000..cb80e12e8a6 --- /dev/null +++ b/queue-4.9/pci-fix-another-sanity-check-bug-in-proc-pci-mmap.patch @@ -0,0 +1,44 @@ +From 17caf56731311c9596e7d38a70c88fcb6afa6a1b Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Wed, 12 Apr 2017 13:25:51 +0100 +Subject: PCI: Fix another sanity check bug in /proc/pci mmap + +From: David Woodhouse + +commit 17caf56731311c9596e7d38a70c88fcb6afa6a1b upstream. + +Don't match MMIO maps with I/O BARs and vice versa. + +Signed-off-by: David Woodhouse +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/proc.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/pci/proc.c ++++ b/drivers/pci/proc.c +@@ -231,14 +231,20 @@ static int proc_bus_pci_mmap(struct file + { + struct pci_dev *dev = PDE_DATA(file_inode(file)); + struct pci_filp_private *fpriv = file->private_data; +- int i, ret, write_combine; ++ int i, ret, write_combine, res_bit; + + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + ++ if (fpriv->mmap_state == pci_mmap_io) ++ res_bit = IORESOURCE_IO; ++ else ++ res_bit = IORESOURCE_MEM; ++ + /* Make sure the caller is mapping a real resource for this device */ + for (i = 0; i < PCI_ROM_RESOURCE; i++) { +- if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) ++ if (dev->resource[i].flags & res_bit && ++ pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) + break; + } + diff --git a/queue-4.9/pci-fix-pci_mmap_fits-for-have_pci_resource_to_user-platforms.patch b/queue-4.9/pci-fix-pci_mmap_fits-for-have_pci_resource_to_user-platforms.patch new file mode 100644 index 00000000000..df2b27c6271 --- /dev/null +++ b/queue-4.9/pci-fix-pci_mmap_fits-for-have_pci_resource_to_user-platforms.patch @@ -0,0 +1,46 @@ +From 6bccc7f426abd640f08d8c75fb22f99483f201b4 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Wed, 12 Apr 2017 13:25:50 +0100 +Subject: PCI: Fix pci_mmap_fits() for HAVE_PCI_RESOURCE_TO_USER platforms + +From: David Woodhouse + +commit 6bccc7f426abd640f08d8c75fb22f99483f201b4 upstream. + +In the PCI_MMAP_PROCFS case when the address being passed by the user is a +'user visible' resource address based on the bus window, and not the actual +contents of the resource, that's what we need to be checking it against. + +Signed-off-by: David Woodhouse +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci-sysfs.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -974,15 +974,19 @@ void pci_remove_legacy_files(struct pci_ + int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, + enum pci_mmap_api mmap_api) + { +- unsigned long nr, start, size, pci_start; ++ unsigned long nr, start, size; ++ resource_size_t pci_start = 0, pci_end; + + if (pci_resource_len(pdev, resno) == 0) + return 0; + nr = vma_pages(vma); + start = vma->vm_pgoff; + size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; +- pci_start = (mmap_api == PCI_MMAP_PROCFS) ? +- pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; ++ if (mmap_api == PCI_MMAP_PROCFS) { ++ pci_resource_to_user(pdev, resno, &pdev->resource[resno], ++ &pci_start, &pci_end); ++ pci_start >>= PAGE_SHIFT; ++ } + if (start >= pci_start && start < pci_start + size && + start + nr <= pci_start + size) + return 1; diff --git a/queue-4.9/pci-freeze-pme-scan-before-suspending-devices.patch b/queue-4.9/pci-freeze-pme-scan-before-suspending-devices.patch new file mode 100644 index 00000000000..5c1d3b56b6e --- /dev/null +++ b/queue-4.9/pci-freeze-pme-scan-before-suspending-devices.patch @@ -0,0 +1,152 @@ +From ea00353f36b64375518662a8ad15e39218a1f324 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Tue, 18 Apr 2017 20:44:30 +0200 +Subject: PCI: Freeze PME scan before suspending devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lukas Wunner + +commit ea00353f36b64375518662a8ad15e39218a1f324 upstream. + +Laurent Pinchart reported that the Renesas R-Car H2 Lager board (r8a7790) +crashes during suspend tests. Geert Uytterhoeven managed to reproduce the +issue on an M2-W Koelsch board (r8a7791): + + It occurs when the PME scan runs, once per second. During PME scan, the + PCI host bridge (rcar-pci) registers are accessed while its module clock + has already been disabled, leading to the crash. + +One reproducer is to configure s2ram to use "s2idle" instead of "deep" +suspend: + + # echo 0 > /sys/module/printk/parameters/console_suspend + # echo s2idle > /sys/power/mem_sleep + # echo mem > /sys/power/state + +Another reproducer is to write either "platform" or "processors" to +/sys/power/pm_test. It does not (or is less likely) to happen during full +system suspend ("core" or "none") because system suspend also disables +timers, and thus the workqueue handling PME scans no longer runs. Geert +believes the issue may still happen in the small window between disabling +module clocks and disabling timers: + + # echo 0 > /sys/module/printk/parameters/console_suspend + # echo platform > /sys/power/pm_test # Or "processors" + # echo mem > /sys/power/state + +(Make sure CONFIG_PCI_RCAR_GEN2 and CONFIG_USB_OHCI_HCD_PCI are enabled.) + +Rafael Wysocki agrees that PME scans should be suspended before the host +bridge registers become inaccessible. To that end, queue the task on a +workqueue that gets frozen before devices suspend. + +Rafael notes however that as a result, some wakeup events may be missed if +they are delivered via PME from a device without working IRQ (which hence +must be polled) and occur after the workqueue has been frozen. If that +turns out to be an issue in practice, it may be possible to solve it by +calling pci_pme_list_scan() once directly from one of the host bridge's +pm_ops callbacks. + +Stacktrace for posterity: + + PM: Syncing filesystems ... [ 38.566237] done. + PM: Preparing system for sleep (mem) + Freezing user space processes ... [ 38.579813] (elapsed 0.001 seconds) done. + Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. + PM: Suspending system (mem) + PM: suspend of devices complete after 152.456 msecs + PM: late suspend of devices complete after 2.809 msecs + PM: noirq suspend of devices complete after 29.863 msecs + suspend debug: Waiting for 5 second(s). + Unhandled fault: asynchronous external abort (0x1211) at 0x00000000 + pgd = c0003000 + [00000000] *pgd=80000040004003, *pmd=00000000 + Internal error: : 1211 [#1] SMP ARM + Modules linked in: + CPU: 1 PID: 20 Comm: kworker/1:1 Not tainted + 4.9.0-rc1-koelsch-00011-g68db9bc814362e7f #3383 + Hardware name: Generic R8A7791 (Flattened Device Tree) + Workqueue: events pci_pme_list_scan + task: eb56e140 task.stack: eb58e000 + PC is at pci_generic_config_read+0x64/0x6c + LR is at rcar_pci_cfg_base+0x64/0x84 + pc : [] lr : [] psr: 600d0093 + sp : eb58fe98 ip : c041d750 fp : 00000008 + r10: c0e2283c r9 : 00000000 r8 : 600d0013 + r7 : 00000008 r6 : eb58fed6 r5 : 00000002 r4 : eb58feb4 + r3 : 00000000 r2 : 00000044 r1 : 00000008 r0 : 00000000 + Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user + Control: 30c5387d Table: 6a9f6c80 DAC: 55555555 + Process kworker/1:1 (pid: 20, stack limit = 0xeb58e210) + Stack: (0xeb58fe98 to 0xeb590000) + fe80: 00000002 00000044 + fea0: eb6f5800 c041d9b0 eb58feb4 00000008 00000044 00000000 eb78a000 eb78a000 + fec0: 00000044 00000000 eb9aff00 c0424bf0 eb78a000 00000000 eb78a000 c0e22830 + fee0: ea8a6fc0 c0424c5c eaae79c0 c0424ce0 eb55f380 c0e22838 eb9a9800 c0235fbc + ff00: eb55f380 c0e22838 eb55f380 eb9a9800 eb9a9800 eb58e000 eb9a9824 c0e02100 + ff20: eb55f398 c02366c4 eb56e140 eb5631c0 00000000 eb55f380 c023641c 00000000 + ff40: 00000000 00000000 00000000 c023a928 cd105598 00000000 40506a34 eb55f380 + ff60: 00000000 00000000 dead4ead ffffffff ffffffff eb58ff74 eb58ff74 00000000 + ff80: 00000000 dead4ead ffffffff ffffffff eb58ff90 eb58ff90 eb58ffac eb5631c0 + ffa0: c023a844 00000000 00000000 c0206d68 00000000 00000000 00000000 00000000 + ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 + ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 3a81336c 10ccd1dd + [] (pci_generic_config_read) from [] + (pci_bus_read_config_word+0x58/0x80) + [] (pci_bus_read_config_word) from [] + (pci_check_pme_status+0x34/0x78) + [] (pci_check_pme_status) from [] (pci_pme_wakeup+0x28/0x54) + [] (pci_pme_wakeup) from [] (pci_pme_list_scan+0x58/0xb4) + [] (pci_pme_list_scan) from [] + (process_one_work+0x1bc/0x308) + [] (process_one_work) from [] (worker_thread+0x2a8/0x3e0) + [] (worker_thread) from [] (kthread+0xe4/0xfc) + [] (kthread) from [] (ret_from_fork+0x14/0x2c) + Code: ea000000 e5903000 f57ff04f e3a00000 (e5843000) + ---[ end trace 667d43ba3aa9e589 ]--- + +Fixes: df17e62e5bff ("PCI: Add support for polling PME state on suspended legacy PCI devices") +Reported-and-tested-by: Laurent Pinchart +Reported-and-tested-by: Geert Uytterhoeven +Signed-off-by: Lukas Wunner +Signed-off-by: Bjorn Helgaas +Reviewed-by: Laurent Pinchart +Acked-by: Rafael J. Wysocki +Cc: Mika Westerberg +Cc: Niklas Söderlund +Cc: Simon Horman +Cc: Yinghai Lu +Cc: Matthew Garrett +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1782,8 +1782,8 @@ static void pci_pme_list_scan(struct wor + } + } + if (!list_empty(&pci_pme_list)) +- schedule_delayed_work(&pci_pme_work, +- msecs_to_jiffies(PME_TIMEOUT)); ++ queue_delayed_work(system_freezable_wq, &pci_pme_work, ++ msecs_to_jiffies(PME_TIMEOUT)); + mutex_unlock(&pci_pme_list_mutex); + } + +@@ -1848,8 +1848,9 @@ void pci_pme_active(struct pci_dev *dev, + mutex_lock(&pci_pme_list_mutex); + list_add(&pme_dev->list, &pci_pme_list); + if (list_is_singular(&pci_pme_list)) +- schedule_delayed_work(&pci_pme_work, +- msecs_to_jiffies(PME_TIMEOUT)); ++ queue_delayed_work(system_freezable_wq, ++ &pci_pme_work, ++ msecs_to_jiffies(PME_TIMEOUT)); + mutex_unlock(&pci_pme_list_mutex); + } else { + mutex_lock(&pci_pme_list_mutex); diff --git a/queue-4.9/pci-hv-allocate-interrupt-descriptors-with-gfp_atomic.patch b/queue-4.9/pci-hv-allocate-interrupt-descriptors-with-gfp_atomic.patch new file mode 100644 index 00000000000..228eaf9c61c --- /dev/null +++ b/queue-4.9/pci-hv-allocate-interrupt-descriptors-with-gfp_atomic.patch @@ -0,0 +1,31 @@ +From 59c58ceeea9cdc6144d7b0303753e6bd26d87455 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Fri, 24 Mar 2017 11:07:22 -0700 +Subject: PCI: hv: Allocate interrupt descriptors with GFP_ATOMIC + +From: K. Y. Srinivasan + +commit 59c58ceeea9cdc6144d7b0303753e6bd26d87455 upstream. + +The memory allocation here needs to be non-blocking. Fix the issue. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Bjorn Helgaas +Reviewed-by: Long Li +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/host/pci-hyperv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/host/pci-hyperv.c ++++ b/drivers/pci/host/pci-hyperv.c +@@ -868,7 +868,7 @@ static void hv_compose_msi_msg(struct ir + hv_int_desc_free(hpdev, int_desc); + } + +- int_desc = kzalloc(sizeof(*int_desc), GFP_KERNEL); ++ int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC); + if (!int_desc) + goto drop_reference; + diff --git a/queue-4.9/pci-hv-specify-cpu_affinity_all-for-msi-affinity-when-32-cpus.patch b/queue-4.9/pci-hv-specify-cpu_affinity_all-for-msi-affinity-when-32-cpus.patch new file mode 100644 index 00000000000..9ee989b5199 --- /dev/null +++ b/queue-4.9/pci-hv-specify-cpu_affinity_all-for-msi-affinity-when-32-cpus.patch @@ -0,0 +1,48 @@ +From 433fcf6b7b31f1f233dd50aeb9d066a0f6ed4b9d Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Fri, 24 Mar 2017 11:07:21 -0700 +Subject: PCI: hv: Specify CPU_AFFINITY_ALL for MSI affinity when >= 32 CPUs + +From: K. Y. Srinivasan + +commit 433fcf6b7b31f1f233dd50aeb9d066a0f6ed4b9d upstream. + +When we have 32 or more CPUs in the affinity mask, we should use a special +constant to specify that to the host. Fix this issue. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Bjorn Helgaas +Reviewed-by: Long Li +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/host/pci-hyperv.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/pci/host/pci-hyperv.c ++++ b/drivers/pci/host/pci-hyperv.c +@@ -72,6 +72,7 @@ enum { + PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1 + }; + ++#define CPU_AFFINITY_ALL -1ULL + #define PCI_CONFIG_MMIO_LENGTH 0x2000 + #define CFG_PAGE_OFFSET 0x1000 + #define CFG_PAGE_SIZE (PCI_CONFIG_MMIO_LENGTH - CFG_PAGE_OFFSET) +@@ -889,9 +890,13 @@ static void hv_compose_msi_msg(struct ir + * processors because Hyper-V only supports 64 in a guest. + */ + affinity = irq_data_get_affinity_mask(data); +- for_each_cpu_and(cpu, affinity, cpu_online_mask) { +- int_pkt->int_desc.cpu_mask |= +- (1ULL << vmbus_cpu_number_to_vp_number(cpu)); ++ if (cpumask_weight(affinity) >= 32) { ++ int_pkt->int_desc.cpu_mask = CPU_AFFINITY_ALL; ++ } else { ++ for_each_cpu_and(cpu, affinity, cpu_online_mask) { ++ int_pkt->int_desc.cpu_mask |= ++ (1ULL << vmbus_cpu_number_to_vp_number(cpu)); ++ } + } + + ret = vmbus_sendpacket(hpdev->hbus->hdev->channel, int_pkt, diff --git a/queue-4.9/pci-only-allow-wc-mmap-on-prefetchable-resources.patch b/queue-4.9/pci-only-allow-wc-mmap-on-prefetchable-resources.patch new file mode 100644 index 00000000000..98e0922b992 --- /dev/null +++ b/queue-4.9/pci-only-allow-wc-mmap-on-prefetchable-resources.patch @@ -0,0 +1,49 @@ +From cef4d02305a06be581bb7f4353446717a1b319ec Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Wed, 12 Apr 2017 13:25:52 +0100 +Subject: PCI: Only allow WC mmap on prefetchable resources + +From: David Woodhouse + +commit cef4d02305a06be581bb7f4353446717a1b319ec upstream. + +The /proc/bus/pci mmap interface allows the user to specify whether they +want WC or not. Don't let them do so on non-prefetchable BARs. + +Signed-off-by: David Woodhouse +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/proc.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/pci/proc.c ++++ b/drivers/pci/proc.c +@@ -231,7 +231,7 @@ static int proc_bus_pci_mmap(struct file + { + struct pci_dev *dev = PDE_DATA(file_inode(file)); + struct pci_filp_private *fpriv = file->private_data; +- int i, ret, write_combine, res_bit; ++ int i, ret, write_combine = 0, res_bit; + + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; +@@ -251,10 +251,13 @@ static int proc_bus_pci_mmap(struct file + if (i >= PCI_ROM_RESOURCE) + return -ENODEV; + +- if (fpriv->mmap_state == pci_mmap_mem) +- write_combine = fpriv->write_combine; +- else +- write_combine = 0; ++ if (fpriv->mmap_state == pci_mmap_mem && ++ fpriv->write_combine) { ++ if (dev->resource[i].flags & IORESOURCE_PREFETCH) ++ write_combine = 1; ++ else ++ return -EINVAL; ++ } + ret = pci_mmap_page_range(dev, vma, + fpriv->mmap_state, write_combine); + if (ret < 0) diff --git a/queue-4.9/series b/queue-4.9/series index b0c8665019f..21596233007 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -142,3 +142,25 @@ uwb-fix-device-quirk-on-big-endian-hosts.patch genirq-fix-chained-interrupt-data-ordering.patch nvme-unmap-cmb-and-remove-sysfs-file-in-reset-path.patch mips-loongson-3-select-mips_l1_cache_shift_6.patch +osf_wait4-fix-infoleak.patch +um-fix-to-call-read_initrd-after-init_bootmem.patch +tracing-kprobes-enforce-kprobes-teardown-after-testing.patch +pci-hv-allocate-interrupt-descriptors-with-gfp_atomic.patch +pci-hv-specify-cpu_affinity_all-for-msi-affinity-when-32-cpus.patch +pci-fix-pci_mmap_fits-for-have_pci_resource_to_user-platforms.patch +pci-fix-another-sanity-check-bug-in-proc-pci-mmap.patch +pci-only-allow-wc-mmap-on-prefetchable-resources.patch +pci-freeze-pme-scan-before-suspending-devices.patch +mtd-nand-orion-fix-clk-handling.patch +mtd-nand-omap2-fix-partition-creation-via-cmdline-mtdparts.patch +mtd-nand-add-ooblayout-for-old-hamming-layout.patch +drm-edid-add-10-bpc-quirk-for-lgd-764-panel-in-hp-zbook-17-g2.patch +nfsd-check-for-oversized-nfsv2-v3-arguments.patch +nfsv4-fix-a-hang-in-open-related-to-server-reboot.patch +nfs-fix-use-after-free-in-write-error-path.patch +nfs-use-gfp_noio-for-two-allocations-in-writeback.patch +nfsd-fix-undefined-behavior-in-nfsd4_layout_verify.patch +nfsd-encoders-mustn-t-use-unitialized-values-in-error-cases.patch +nfsd-fix-up-the-supattr_exclcreat-attributes.patch +drivers-char-mem-check-for-address-space-wraparound-with-mmap.patch +drm-i915-gvt-disable-access-to-stolen-memory-as-a-guest.patch diff --git a/queue-4.9/tracing-kprobes-enforce-kprobes-teardown-after-testing.patch b/queue-4.9/tracing-kprobes-enforce-kprobes-teardown-after-testing.patch new file mode 100644 index 00000000000..0eac24bb378 --- /dev/null +++ b/queue-4.9/tracing-kprobes-enforce-kprobes-teardown-after-testing.patch @@ -0,0 +1,77 @@ +From 30e7d894c1478c88d50ce94ddcdbd7f9763d9cdd Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 17 May 2017 10:19:49 +0200 +Subject: tracing/kprobes: Enforce kprobes teardown after testing + +From: Thomas Gleixner + +commit 30e7d894c1478c88d50ce94ddcdbd7f9763d9cdd upstream. + +Enabling the tracer selftest triggers occasionally the warning in +text_poke(), which warns when the to be modified page is not marked +reserved. + +The reason is that the tracer selftest installs kprobes on functions marked +__init for testing. These probes are removed after the tests, but that +removal schedules the delayed kprobes_optimizer work, which will do the +actual text poke. If the work is executed after the init text is freed, +then the warning triggers. The bug can be reproduced reliably when the work +delay is increased. + +Flush the optimizer work and wait for the optimizing/unoptimizing lists to +become empty before returning from the kprobes tracer selftest. That +ensures that all operations which were queued due to the probes removal +have completed. + +Link: http://lkml.kernel.org/r/20170516094802.76a468bb@gandalf.local.home + +Signed-off-by: Thomas Gleixner +Acked-by: Masami Hiramatsu +Fixes: 6274de498 ("kprobes: Support delayed unoptimizing") +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/kprobes.h | 4 +++- + kernel/kprobes.c | 2 +- + kernel/trace/trace_kprobe.c | 5 +++++ + 3 files changed, 9 insertions(+), 2 deletions(-) + +--- a/include/linux/kprobes.h ++++ b/include/linux/kprobes.h +@@ -330,7 +330,9 @@ extern int proc_kprobes_optimization_han + int write, void __user *buffer, + size_t *length, loff_t *ppos); + #endif +- ++extern void wait_for_kprobe_optimizer(void); ++#else ++static inline void wait_for_kprobe_optimizer(void) { } + #endif /* CONFIG_OPTPROBES */ + #ifdef CONFIG_KPROBES_ON_FTRACE + extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -563,7 +563,7 @@ static void kprobe_optimizer(struct work + } + + /* Wait for completing optimization and unoptimization */ +-static void wait_for_kprobe_optimizer(void) ++void wait_for_kprobe_optimizer(void) + { + mutex_lock(&kprobe_mutex); + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -1484,6 +1484,11 @@ static __init int kprobe_trace_self_test + + end: + release_all_trace_kprobes(); ++ /* ++ * Wait for the optimizer work to finish. Otherwise it might fiddle ++ * with probes in already freed __init text. ++ */ ++ wait_for_kprobe_optimizer(); + if (warn) + pr_cont("NG: Some tests are failed. Please check them.\n"); + else diff --git a/queue-4.9/um-fix-to-call-read_initrd-after-init_bootmem.patch b/queue-4.9/um-fix-to-call-read_initrd-after-init_bootmem.patch new file mode 100644 index 00000000000..8f876a7d0ce --- /dev/null +++ b/queue-4.9/um-fix-to-call-read_initrd-after-init_bootmem.patch @@ -0,0 +1,65 @@ +From 5b4236e17cc1bd9fa14b2b0c7a4ae632d41f2e20 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Thu, 27 Apr 2017 12:15:10 +0900 +Subject: um: Fix to call read_initrd after init_bootmem + +From: Masami Hiramatsu + +commit 5b4236e17cc1bd9fa14b2b0c7a4ae632d41f2e20 upstream. + +Since read_initrd() invokes alloc_bootmem() for allocating +memory to load initrd image, it must be called after init_bootmem. + +This makes read_initrd() called directly from setup_arch() +after init_bootmem() and mem_total_pages(). + +Fixes: b63236972e1 ("um: Setup physical memory in setup_arch()") +Signed-off-by: Masami Hiramatsu +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + arch/um/kernel/initrd.c | 4 +--- + arch/um/kernel/um_arch.c | 6 ++++++ + 2 files changed, 7 insertions(+), 3 deletions(-) + +--- a/arch/um/kernel/initrd.c ++++ b/arch/um/kernel/initrd.c +@@ -14,7 +14,7 @@ + static char *initrd __initdata = NULL; + static int load_initrd(char *filename, void *buf, int size); + +-static int __init read_initrd(void) ++int __init read_initrd(void) + { + void *area; + long long size; +@@ -46,8 +46,6 @@ static int __init read_initrd(void) + return 0; + } + +-__uml_postsetup(read_initrd); +- + static int __init uml_initrd_setup(char *line, int *add) + { + initrd = line; +--- a/arch/um/kernel/um_arch.c ++++ b/arch/um/kernel/um_arch.c +@@ -336,11 +336,17 @@ int __init linux_main(int argc, char **a + return start_uml(); + } + ++int __init __weak read_initrd(void) ++{ ++ return 0; ++} ++ + void __init setup_arch(char **cmdline_p) + { + stack_protections((unsigned long) &init_thread_info); + setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); + mem_total_pages(physmem_size, iomem_size, highmem); ++ read_initrd(); + + paging_init(); + strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);