From: Greg Kroah-Hartman Date: Fri, 23 Oct 2015 17:42:06 +0000 (-0700) Subject: 4.2-stable patches X-Git-Tag: v3.14.56~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2887ff89ef7ebfb68efa6789084ba29218b0507e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.2-stable patches added patches: arm64-fix-thp-protection-change-logic.patch pinctrl-imx25-ensure-that-a-pin-with-id-i-is-at-position-i-in-the-info-array.patch rbd-fix-double-free-on-rbd_dev-header_name.patch svcrdma-handle-rdma-read-with-a-non-zero-initial-page-offset.patch timekeeping-increment-clock_was_set_seq-in-timekeeping_init.patch --- diff --git a/queue-4.2/arm64-fix-thp-protection-change-logic.patch b/queue-4.2/arm64-fix-thp-protection-change-logic.patch new file mode 100644 index 00000000000..c60c5f9acb8 --- /dev/null +++ b/queue-4.2/arm64-fix-thp-protection-change-logic.patch @@ -0,0 +1,63 @@ +From 1a541b4e3cd6f5795022514114854b3e1345f24e Mon Sep 17 00:00:00 2001 +From: Steve Capper +Date: Thu, 1 Oct 2015 13:06:07 +0100 +Subject: arm64: Fix THP protection change logic + +From: Steve Capper + +commit 1a541b4e3cd6f5795022514114854b3e1345f24e upstream. + +6910fa1 ("arm64: enable PTE type bit in the mask for pte_modify") fixes +a problem whereby a large block of PROT_NONE mapped memory is +incorrectly mapped as block descriptors when mprotect is called. + +Unfortunately, a subtle bug was introduced by this fix to the THP logic. + +If one mmaps a large block of memory, then faults it such that it is +collapsed into THPs; resulting calls to mprotect on this area of memory +will lead to incorrect table descriptors being written instead of block +descriptors. This is because pmd_modify calls pte_modify which is now +allowed to modify the type of the page table entry. + +This patch reverts commit 6910fa16dbe142f6a0fd0fd7c249f9883ff7fc8a, and +fixes the problem it was trying to address by adjusting PAGE_NONE to +represent a table entry. Thus no change in pte type is required when +moving from PROT_NONE to a different protection. + +Fixes: 6910fa16dbe1 ("arm64: enable PTE type bit in the mask for pte_modify") +Cc: # 4.0+ +Cc: Feng Kan +Reported-by: Ganapatrao Kulkarni +Tested-by: Ganapatrao Kulkarni +Reviewed-by: Catalin Marinas +[SteveC: backported 1a541b4e3cd6f5795022514114854b3e1345f24e to 4.1 and + 4.2 stable. Just one minor fix to second part to allow patch to apply +cleanly, no logic changed.] +Signed-off-by: Steve Capper +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/pgtable.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -80,7 +80,7 @@ extern void __pgd_error(const char *file + #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) + #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN) + +-#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) ++#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) + #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) + #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) + #define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) +@@ -460,7 +460,7 @@ static inline pud_t *pud_offset(pgd_t *p + static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) + { + const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | +- PTE_PROT_NONE | PTE_WRITE | PTE_TYPE_MASK; ++ PTE_PROT_NONE | PTE_VALID | PTE_WRITE; + pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); + return pte; + } diff --git a/queue-4.2/pinctrl-imx25-ensure-that-a-pin-with-id-i-is-at-position-i-in-the-info-array.patch b/queue-4.2/pinctrl-imx25-ensure-that-a-pin-with-id-i-is-at-position-i-in-the-info-array.patch new file mode 100644 index 00000000000..52007293a62 --- /dev/null +++ b/queue-4.2/pinctrl-imx25-ensure-that-a-pin-with-id-i-is-at-position-i-in-the-info-array.patch @@ -0,0 +1,69 @@ +From 9911a2d5e9d14e39692b751929a92cb5a1d9d0e0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Wed, 23 Sep 2015 16:35:09 +0200 +Subject: pinctrl: imx25: ensure that a pin with id i is at position i in the info array +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= + +commit 9911a2d5e9d14e39692b751929a92cb5a1d9d0e0 upstream. + +The code in pinctrl-imx.c only works correctly if in the +imx_pinctrl_soc_info passed to imx_pinctrl_probe we have: + + info->pins[i].number = i + conf_reg(info->pins[i]) = 4 * i + +(which conf_reg(pin) being the offset of the pin's configuration +register). + +When the imx25 specific part was introduced in b4a87c9b966f ("pinctrl: +pinctrl-imx: add imx25 pinctrl driver") we had: + + info->pins[i].number = i + 1 + conf_reg(info->pins[i]) = 4 * i + +. Commit 34027ca2bbc6 ("pinctrl: imx25: fix numbering for pins") tried +to fix that but made the situation: + + info->pins[i-1].number = i + conf_reg(info->pins[i-1]) = 4 * i + +which is hardly better but fixed the error seen back then. + +So insert another reserved entry in the array to finally yield: + + info->pins[i].number = i + conf_reg(info->pins[i]) = 4 * i + +Fixes: 34027ca2bbc6 ("pinctrl: imx25: fix numbering for pins") +Signed-off-by: Uwe Kleine-König +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pinctrl/freescale/pinctrl-imx25.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/pinctrl/freescale/pinctrl-imx25.c ++++ b/drivers/pinctrl/freescale/pinctrl-imx25.c +@@ -26,7 +26,8 @@ + #include "pinctrl-imx.h" + + enum imx25_pads { +- MX25_PAD_RESERVE0 = 1, ++ MX25_PAD_RESERVE0 = 0, ++ MX25_PAD_RESERVE1 = 1, + MX25_PAD_A10 = 2, + MX25_PAD_A13 = 3, + MX25_PAD_A14 = 4, +@@ -169,6 +170,7 @@ enum imx25_pads { + /* Pad names for the pinmux subsystem */ + static const struct pinctrl_pin_desc imx25_pinctrl_pads[] = { + IMX_PINCTRL_PIN(MX25_PAD_RESERVE0), ++ IMX_PINCTRL_PIN(MX25_PAD_RESERVE1), + IMX_PINCTRL_PIN(MX25_PAD_A10), + IMX_PINCTRL_PIN(MX25_PAD_A13), + IMX_PINCTRL_PIN(MX25_PAD_A14), diff --git a/queue-4.2/rbd-fix-double-free-on-rbd_dev-header_name.patch b/queue-4.2/rbd-fix-double-free-on-rbd_dev-header_name.patch new file mode 100644 index 00000000000..4108d056e69 --- /dev/null +++ b/queue-4.2/rbd-fix-double-free-on-rbd_dev-header_name.patch @@ -0,0 +1,35 @@ +From 3ebe138ac642a195c7f2efdb918f464734421fd6 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Mon, 31 Aug 2015 15:21:39 +0300 +Subject: rbd: fix double free on rbd_dev->header_name + +From: Ilya Dryomov + +commit 3ebe138ac642a195c7f2efdb918f464734421fd6 upstream. + +If rbd_dev_image_probe() in rbd_dev_probe_parent() fails, header_name +is freed twice: once in rbd_dev_probe_parent() and then in its caller +rbd_dev_image_probe() (rbd_dev_image_probe() is called recursively to +handle parent images). + +rbd_dev_probe_parent() is responsible for probing the parent, so it +shouldn't muck with clone's fields. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Alex Elder +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/rbd.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -5201,7 +5201,6 @@ static int rbd_dev_probe_parent(struct r + out_err: + if (parent) { + rbd_dev_unparent(rbd_dev); +- kfree(rbd_dev->header_name); + rbd_dev_destroy(parent); + } else { + rbd_put_client(rbdc); diff --git a/queue-4.2/series b/queue-4.2/series index b411c17df52..599c5929a0c 100644 --- a/queue-4.2/series +++ b/queue-4.2/series @@ -47,3 +47,8 @@ drm-amdgpu-fix-num_crtc-on-cz.patch drm-amdgpu-check-before-checking-pci-bridge-registers.patch drm-amdgpu-keep-the-pflip-interrupts-always-enabled-v7.patch dm-thin-fix-missing-pool-reference-count-decrement-in-pool_ctr-error-path.patch +rbd-fix-double-free-on-rbd_dev-header_name.patch +timekeeping-increment-clock_was_set_seq-in-timekeeping_init.patch +pinctrl-imx25-ensure-that-a-pin-with-id-i-is-at-position-i-in-the-info-array.patch +arm64-fix-thp-protection-change-logic.patch +svcrdma-handle-rdma-read-with-a-non-zero-initial-page-offset.patch diff --git a/queue-4.2/svcrdma-handle-rdma-read-with-a-non-zero-initial-page-offset.patch b/queue-4.2/svcrdma-handle-rdma-read-with-a-non-zero-initial-page-offset.patch new file mode 100644 index 00000000000..9ae3fd3129a --- /dev/null +++ b/queue-4.2/svcrdma-handle-rdma-read-with-a-non-zero-initial-page-offset.patch @@ -0,0 +1,57 @@ +From c91aed9896946721bb30705ea2904edb3725dd61 Mon Sep 17 00:00:00 2001 +From: Steve Wise +Date: Mon, 28 Sep 2015 16:46:06 -0500 +Subject: svcrdma: handle rdma read with a non-zero initial page offset + +From: Steve Wise + +commit c91aed9896946721bb30705ea2904edb3725dd61 upstream. + +The server rdma_read_chunk_lcl() and rdma_read_chunk_frmr() functions +were not taking into account the initial page_offset when determining +the rdma read length. This resulted in a read who's starting address +and length exceeded the base/bounds of the frmr. + +The server gets an async error from the rdma device and kills the +connection, and the client then reconnects and resends. This repeats +indefinitely, and the application hangs. + +Most work loads don't tickle this bug apparently, but one test hit it +every time: building the linux kernel on a 16 core node with 'make -j +16 O=/mnt/0' where /mnt/0 is a ramdisk mounted via NFSRDMA. + +This bug seems to only be tripped with devices having small fastreg page +list depths. I didn't see it with mlx4, for instance. + +Fixes: 0bf4828983df ('svcrdma: refactor marshalling logic') +Signed-off-by: Steve Wise +Tested-by: Chuck Lever +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c ++++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +@@ -146,7 +146,8 @@ int rdma_read_chunk_lcl(struct svcxprt_r + ctxt->read_hdr = head; + pages_needed = + min_t(int, pages_needed, rdma_read_max_sge(xprt, pages_needed)); +- read = min_t(int, pages_needed << PAGE_SHIFT, rs_length); ++ read = min_t(int, (pages_needed << PAGE_SHIFT) - *page_offset, ++ rs_length); + + for (pno = 0; pno < pages_needed; pno++) { + int len = min_t(int, rs_length, PAGE_SIZE - pg_off); +@@ -245,7 +246,8 @@ int rdma_read_chunk_frmr(struct svcxprt_ + ctxt->direction = DMA_FROM_DEVICE; + ctxt->frmr = frmr; + pages_needed = min_t(int, pages_needed, xprt->sc_frmr_pg_list_len); +- read = min_t(int, pages_needed << PAGE_SHIFT, rs_length); ++ read = min_t(int, (pages_needed << PAGE_SHIFT) - *page_offset, ++ rs_length); + + frmr->kva = page_address(rqstp->rq_arg.pages[pg_no]); + frmr->direction = DMA_FROM_DEVICE; diff --git a/queue-4.2/timekeeping-increment-clock_was_set_seq-in-timekeeping_init.patch b/queue-4.2/timekeeping-increment-clock_was_set_seq-in-timekeeping_init.patch new file mode 100644 index 00000000000..b39137c871f --- /dev/null +++ b/queue-4.2/timekeeping-increment-clock_was_set_seq-in-timekeeping_init.patch @@ -0,0 +1,38 @@ +From 56fd16cabac9cd8f15e2902898a9d0cc96e2fa70 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Fri, 16 Oct 2015 15:50:22 +0200 +Subject: timekeeping: Increment clock_was_set_seq in timekeeping_init() + +From: Thomas Gleixner + +commit 56fd16cabac9cd8f15e2902898a9d0cc96e2fa70 upstream. + +timekeeping_init() can set the wall time offset, so we need to +increment the clock_was_set_seq counter. That way hrtimers will pick +up the early offset immediately. Otherwise on a machine which does not +set wall time later in the boot process the hrtimer offset is stale at +0 and wall time timers are going to expire with a delay of 45 years. + +Fixes: 868a3e915f7f "hrtimer: Make offset update smarter" +Reported-and-tested-by: Heiko Carstens +Signed-off-by: Thomas Gleixner +Cc: Stefan Liebler +Cc: Peter Zijlstra +Cc: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -1244,7 +1244,7 @@ void __init timekeeping_init(void) + set_normalized_timespec64(&tmp, -boot.tv_sec, -boot.tv_nsec); + tk_set_wall_to_mono(tk, tmp); + +- timekeeping_update(tk, TK_MIRROR); ++ timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); + + write_seqcount_end(&tk_core.seq); + raw_spin_unlock_irqrestore(&timekeeper_lock, flags);