]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Jun 2017 07:00:41 +0000 (09:00 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Jun 2017 07:00:41 +0000 (09:00 +0200)
added patches:
brcmfmac-add-parameter-to-pass-error-code-in-firmware-callback.patch
brcmfmac-unbind-all-devices-upon-failure-in-firmware-callback.patch
brcmfmac-use-firmware-callback-upon-failure-to-load.patch
input-i8042-add-fujitsu-lifebook-ah544-to-notimeout-list.patch
powerpc-64s-handle-data-breakpoints-in-radix-mode.patch
powerpc-kprobes-pause-function_graph-tracing-during-jprobes-handling.patch
time-fix-clock-read-clock-race-around-clocksource-changes.patch
time-fix-clock_monotonic_raw-sub-nanosecond-accounting.patch

queue-4.9/brcmfmac-add-parameter-to-pass-error-code-in-firmware-callback.patch [new file with mode: 0644]
queue-4.9/brcmfmac-unbind-all-devices-upon-failure-in-firmware-callback.patch [new file with mode: 0644]
queue-4.9/brcmfmac-use-firmware-callback-upon-failure-to-load.patch [new file with mode: 0644]
queue-4.9/input-i8042-add-fujitsu-lifebook-ah544-to-notimeout-list.patch [new file with mode: 0644]
queue-4.9/powerpc-64s-handle-data-breakpoints-in-radix-mode.patch [new file with mode: 0644]
queue-4.9/powerpc-kprobes-pause-function_graph-tracing-during-jprobes-handling.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/time-fix-clock-read-clock-race-around-clocksource-changes.patch [new file with mode: 0644]
queue-4.9/time-fix-clock_monotonic_raw-sub-nanosecond-accounting.patch [new file with mode: 0644]

diff --git a/queue-4.9/brcmfmac-add-parameter-to-pass-error-code-in-firmware-callback.patch b/queue-4.9/brcmfmac-add-parameter-to-pass-error-code-in-firmware-callback.patch
new file mode 100644 (file)
index 0000000..1fd6d5e
--- /dev/null
@@ -0,0 +1,180 @@
+From 6d0507a777fbc533f7f1bf5664a81982dd50dece Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 12 Jun 2017 12:47:32 +0100
+Subject: brcmfmac: add parameter to pass error code in firmware callback
+
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+
+commit 6d0507a777fbc533f7f1bf5664a81982dd50dece upstream.
+
+Extend the parameters in the firmware callback so it can be called
+upon success and failure. This allows the caller to properly clear
+all resources in the failure path. Right now the error code is
+always zero, ie. success.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |   10 +++----
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |    4 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c     |   17 ++++++++----
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c     |   17 +++++++-----
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c      |    6 ++--
+ 5 files changed, 34 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -442,7 +442,7 @@ struct brcmf_fw {
+       const char *nvram_name;
+       u16 domain_nr;
+       u16 bus_nr;
+-      void (*done)(struct device *dev, const struct firmware *fw,
++      void (*done)(struct device *dev, int err, const struct firmware *fw,
+                    void *nvram_image, u32 nvram_len);
+ };
+@@ -477,7 +477,7 @@ static void brcmf_fw_request_nvram_done(
+       if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
+               goto fail;
+-      fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
++      fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length);
+       kfree(fwctx);
+       return;
+@@ -499,7 +499,7 @@ static void brcmf_fw_request_code_done(c
+       /* only requested code so done here */
+       if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
+-              fwctx->done(fwctx->dev, fw, NULL, 0);
++              fwctx->done(fwctx->dev, 0, fw, NULL, 0);
+               kfree(fwctx);
+               return;
+       }
+@@ -522,7 +522,7 @@ fail:
+ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
+                               const char *code, const char *nvram,
+-                              void (*fw_cb)(struct device *dev,
++                              void (*fw_cb)(struct device *dev, int err,
+                                             const struct firmware *fw,
+                                             void *nvram_image, u32 nvram_len),
+                               u16 domain_nr, u16 bus_nr)
+@@ -555,7 +555,7 @@ int brcmf_fw_get_firmwares_pcie(struct d
+ int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
+                          const char *code, const char *nvram,
+-                         void (*fw_cb)(struct device *dev,
++                         void (*fw_cb)(struct device *dev, int err,
+                                        const struct firmware *fw,
+                                        void *nvram_image, u32 nvram_len))
+ {
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
+@@ -73,13 +73,13 @@ void brcmf_fw_nvram_free(void *nvram);
+  */
+ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
+                               const char *code, const char *nvram,
+-                              void (*fw_cb)(struct device *dev,
++                              void (*fw_cb)(struct device *dev, int err,
+                                             const struct firmware *fw,
+                                             void *nvram_image, u32 nvram_len),
+                               u16 domain_nr, u16 bus_nr);
+ int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
+                          const char *code, const char *nvram,
+-                         void (*fw_cb)(struct device *dev,
++                         void (*fw_cb)(struct device *dev, int err,
+                                        const struct firmware *fw,
+                                        void *nvram_image, u32 nvram_len));
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -1618,16 +1618,23 @@ static const struct brcmf_buscore_ops br
+       .write32 = brcmf_pcie_buscore_write32,
+ };
+-static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
++static void brcmf_pcie_setup(struct device *dev, int ret,
++                           const struct firmware *fw,
+                            void *nvram, u32 nvram_len)
+ {
+-      struct brcmf_bus *bus = dev_get_drvdata(dev);
+-      struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie;
+-      struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
++      struct brcmf_bus *bus;
++      struct brcmf_pciedev *pcie_bus_dev;
++      struct brcmf_pciedev_info *devinfo;
+       struct brcmf_commonring **flowrings;
+-      int ret;
+       u32 i;
++      /* check firmware loading result */
++      if (ret)
++              goto fail;
++
++      bus = dev_get_drvdata(dev);
++      pcie_bus_dev = bus->bus_priv.pcie;
++      devinfo = pcie_bus_dev->devinfo;
+       brcmf_pcie_attach(devinfo);
+       /* Some of the firmwares have the size of the memory of the device
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3975,21 +3975,26 @@ static const struct brcmf_bus_ops brcmf_
+       .get_memdump = brcmf_sdio_bus_get_memdump,
+ };
+-static void brcmf_sdio_firmware_callback(struct device *dev,
++static void brcmf_sdio_firmware_callback(struct device *dev, int err,
+                                        const struct firmware *code,
+                                        void *nvram, u32 nvram_len)
+ {
+-      struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+-      struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+-      struct brcmf_sdio *bus = sdiodev->bus;
+-      int err = 0;
++      struct brcmf_bus *bus_if;
++      struct brcmf_sdio_dev *sdiodev;
++      struct brcmf_sdio *bus;
+       u8 saveclk;
+-      brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev));
++      brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
++      if (err)
++              goto fail;
++      bus_if = dev_get_drvdata(dev);
+       if (!bus_if->drvr)
+               return;
++      sdiodev = bus_if->bus_priv.sdio;
++      bus = sdiodev->bus;
++
+       /* try to download image and nvram to the dongle */
+       bus->alp_only = true;
+       err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+@@ -1158,13 +1158,15 @@ fail:
+       return ret;
+ }
+-static void brcmf_usb_probe_phase2(struct device *dev,
++static void brcmf_usb_probe_phase2(struct device *dev, int ret,
+                                  const struct firmware *fw,
+                                  void *nvram, u32 nvlen)
+ {
+       struct brcmf_bus *bus = dev_get_drvdata(dev);
+       struct brcmf_usbdev_info *devinfo;
+-      int ret;
++
++      if (ret)
++              goto error;
+       brcmf_dbg(USB, "Start fw downloading\n");
diff --git a/queue-4.9/brcmfmac-unbind-all-devices-upon-failure-in-firmware-callback.patch b/queue-4.9/brcmfmac-unbind-all-devices-upon-failure-in-firmware-callback.patch
new file mode 100644 (file)
index 0000000..fd13578
--- /dev/null
@@ -0,0 +1,54 @@
+From 7a51461fc2da82a6c565a3ee65c41c197f28225d Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 12 Jun 2017 12:47:34 +0100
+Subject: brcmfmac: unbind all devices upon failure in firmware callback
+
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+
+commit 7a51461fc2da82a6c565a3ee65c41c197f28225d upstream.
+
+When request firmware fails, brcmf_ops_sdio_remove is being called and
+brcmf_bus freed. In such circumstancies if you do a suspend/resume cycle
+the kernel hangs on resume due a NULL pointer dereference in resume
+function. So in brcmf_sdio_firmware_callback() we need to unbind the
+driver from both sdio_func devices when firmware load failure is indicated.
+
+Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3985,14 +3985,14 @@ static void brcmf_sdio_firmware_callback
+       u8 saveclk;
+       brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
++      bus_if = dev_get_drvdata(dev);
++      sdiodev = bus_if->bus_priv.sdio;
+       if (err)
+               goto fail;
+-      bus_if = dev_get_drvdata(dev);
+       if (!bus_if->drvr)
+               return;
+-      sdiodev = bus_if->bus_priv.sdio;
+       bus = sdiodev->bus;
+       /* try to download image and nvram to the dongle */
+@@ -4081,6 +4081,7 @@ release:
+ fail:
+       brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
+       device_release_driver(dev);
++      device_release_driver(&sdiodev->func[2]->dev);
+ }
+ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
diff --git a/queue-4.9/brcmfmac-use-firmware-callback-upon-failure-to-load.patch b/queue-4.9/brcmfmac-use-firmware-callback-upon-failure-to-load.patch
new file mode 100644 (file)
index 0000000..0fcefb4
--- /dev/null
@@ -0,0 +1,81 @@
+From 03fb0e8393fae8ebb6710a99387853ed0becbc8e Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 12 Jun 2017 12:47:33 +0100
+Subject: brcmfmac: use firmware callback upon failure to load
+
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+
+commit 03fb0e8393fae8ebb6710a99387853ed0becbc8e upstream.
+
+When firmware loading failed the code used to unbind the device provided
+by the calling code. However, for the sdio driver two devices are bound
+and both need to be released upon failure. The callback has been extended
+with parameter to pass error code so add that in this commit upon firmware
+loading failure.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |   27 +++++-------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -484,39 +484,38 @@ static void brcmf_fw_request_nvram_done(
+ fail:
+       brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
+       release_firmware(fwctx->code);
+-      device_release_driver(fwctx->dev);
++      fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0);
+       kfree(fwctx);
+ }
+ static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
+ {
+       struct brcmf_fw *fwctx = ctx;
+-      int ret;
++      int ret = 0;
+       brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
+-      if (!fw)
++      if (!fw) {
++              ret = -ENOENT;
+               goto fail;
+-
+-      /* only requested code so done here */
+-      if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
+-              fwctx->done(fwctx->dev, 0, fw, NULL, 0);
+-              kfree(fwctx);
+-              return;
+       }
++      /* only requested code so done here */
++      if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM))
++              goto done;
++
+       fwctx->code = fw;
+       ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
+                                     fwctx->dev, GFP_KERNEL, fwctx,
+                                     brcmf_fw_request_nvram_done);
+-      if (!ret)
+-              return;
+-
+-      brcmf_fw_request_nvram_done(NULL, fwctx);
++      /* pass NULL to nvram callback for bcm47xx fallback */
++      if (ret)
++              brcmf_fw_request_nvram_done(NULL, fwctx);
+       return;
+ fail:
+       brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
+-      device_release_driver(fwctx->dev);
++done:
++      fwctx->done(fwctx->dev, ret, fw, NULL, 0);
+       kfree(fwctx);
+ }
diff --git a/queue-4.9/input-i8042-add-fujitsu-lifebook-ah544-to-notimeout-list.patch b/queue-4.9/input-i8042-add-fujitsu-lifebook-ah544-to-notimeout-list.patch
new file mode 100644 (file)
index 0000000..ad2cf46
--- /dev/null
@@ -0,0 +1,40 @@
+From 817ae460c784f32cd45e60b2b1b21378c3c6a847 Mon Sep 17 00:00:00 2001
+From: Daniel Drake <drake@endlessm.com>
+Date: Mon, 19 Jun 2017 19:48:52 -0700
+Subject: Input: i8042 - add Fujitsu Lifebook AH544 to notimeout list
+
+From: Daniel Drake <drake@endlessm.com>
+
+commit 817ae460c784f32cd45e60b2b1b21378c3c6a847 upstream.
+
+Without this quirk, the touchpad is not responsive on this product, with
+the following message repeated in the logs:
+
+ psmouse serio1: bad data from KBC - timeout
+
+Add it to the notimeout list alongside other similar Fujitsu laptops.
+
+Signed-off-by: Daniel Drake <drake@endlessm.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/serio/i8042-x86ia64io.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -788,6 +788,13 @@ static const struct dmi_system_id __init
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
+               },
+       },
++      {
++              /* Fujitsu UH554 laptop */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
++              },
++      },
+       { }
+ };
diff --git a/queue-4.9/powerpc-64s-handle-data-breakpoints-in-radix-mode.patch b/queue-4.9/powerpc-64s-handle-data-breakpoints-in-radix-mode.patch
new file mode 100644 (file)
index 0000000..48ebd6e
--- /dev/null
@@ -0,0 +1,75 @@
+From d89ba5353f301971dd7d2f9fdf25c4432728f38e Mon Sep 17 00:00:00 2001
+From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
+Date: Wed, 14 Jun 2017 00:12:00 +0530
+Subject: powerpc/64s: Handle data breakpoints in Radix mode
+
+From: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+
+commit d89ba5353f301971dd7d2f9fdf25c4432728f38e upstream.
+
+On Power9, trying to use data breakpoints throws the splat shown
+below. This is because the check for a data breakpoint in DSISR is in
+do_hash_page(), which is not called when in Radix mode.
+
+  Unable to handle kernel paging request for data at address 0xc000000000e19218
+  Faulting instruction address: 0xc0000000001155e8
+  cpu 0x0: Vector: 300 (Data Access) at [c0000000ef1e7b20]
+  pc: c0000000001155e8: find_pid_ns+0x48/0xe0
+  lr: c000000000116ac4: find_task_by_vpid+0x44/0x90
+  sp: c0000000ef1e7da0
+  msr: 9000000000009033
+  dar: c000000000e19218
+  dsisr: 400000
+
+Move the check to handle_page_fault() so as to catch data breakpoints
+in both Hash and Radix MMU modes.
+
+We have to change the check in do_hash_page() against 0xa410 to use
+0xa450, so as to include the value of (DSISR_DABRMATCH << 16).
+
+There are two sites that call handle_page_fault() when in Radix, both
+already pass DSISR in r4.
+
+Fixes: caca285e5ab4 ("powerpc/mm/radix: Use STD_MMU_64 to properly isolate hash related code")
+Reported-by: Shriya R. Kulkarni <shriykul@in.ibm.com>
+Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+[mpe: Fix the fall-through case on hash, we need to reload DSISR]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/exceptions-64s.S |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -1411,10 +1411,8 @@ USE_TEXT_SECTION()
+       .align  7
+ do_hash_page:
+ #ifdef CONFIG_PPC_STD_MMU_64
+-      andis.  r0,r4,0xa410            /* weird error? */
++      andis.  r0,r4,0xa450            /* weird error? */
+       bne-    handle_page_fault       /* if not, try to insert a HPTE */
+-      andis.  r0,r4,DSISR_DABRMATCH@h
+-      bne-    handle_dabr_fault
+       CURRENT_THREAD_INFO(r11, r1)
+       lwz     r0,TI_PREEMPT(r11)      /* If we're in an "NMI" */
+       andis.  r0,r0,NMI_MASK@h        /* (i.e. an irq when soft-disabled) */
+@@ -1438,11 +1436,16 @@ do_hash_page:
+       /* Error */
+       blt-    13f
++
++      /* Reload DSISR into r4 for the DABR check below */
++      ld      r4,_DSISR(r1)
+ #endif /* CONFIG_PPC_STD_MMU_64 */
+ /* Here we have a page fault that hash_page can't handle. */
+ handle_page_fault:
+-11:   ld      r4,_DAR(r1)
++11:   andis.  r0,r4,DSISR_DABRMATCH@h
++      bne-    handle_dabr_fault
++      ld      r4,_DAR(r1)
+       ld      r5,_DSISR(r1)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      do_page_fault
diff --git a/queue-4.9/powerpc-kprobes-pause-function_graph-tracing-during-jprobes-handling.patch b/queue-4.9/powerpc-kprobes-pause-function_graph-tracing-during-jprobes-handling.patch
new file mode 100644 (file)
index 0000000..8e71bc5
--- /dev/null
@@ -0,0 +1,57 @@
+From a9f8553e935f26cb5447f67e280946b0923cd2dc Mon Sep 17 00:00:00 2001
+From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
+Date: Thu, 1 Jun 2017 16:18:15 +0530
+Subject: powerpc/kprobes: Pause function_graph tracing during jprobes handling
+
+From: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+
+commit a9f8553e935f26cb5447f67e280946b0923cd2dc upstream.
+
+This fixes a crash when function_graph and jprobes are used together.
+This is essentially commit 237d28db036e ("ftrace/jprobes/x86: Fix
+conflict between jprobes and function graph tracing"), but for powerpc.
+
+Jprobes breaks function_graph tracing since the jprobe hook needs to use
+jprobe_return(), which never returns back to the hook, but instead to
+the original jprobe'd function. The solution is to momentarily pause
+function_graph tracing before invoking the jprobe hook and re-enable it
+when returning back to the original jprobe'd function.
+
+Fixes: 6794c78243bf ("powerpc64: port of the function graph tracer")
+Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
+Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/kprobes.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/arch/powerpc/kernel/kprobes.c
++++ b/arch/powerpc/kernel/kprobes.c
+@@ -511,6 +511,15 @@ int __kprobes setjmp_pre_handler(struct
+       regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
+ #endif
++      /*
++       * jprobes use jprobe_return() which skips the normal return
++       * path of the function, and this messes up the accounting of the
++       * function graph tracer.
++       *
++       * Pause function graph tracing while performing the jprobe function.
++       */
++      pause_graph_tracing();
++
+       return 1;
+ }
+@@ -533,6 +542,8 @@ int __kprobes longjmp_break_handler(stru
+        * saved regs...
+        */
+       memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
++      /* It's OK to start function graph tracing again */
++      unpause_graph_tracing();
+       preempt_enable_no_resched();
+       return 1;
+ }
index d9239fbfba6b2eb37ad2a1388456dda36d68286f..85391e9f725bca95b73ad3a5c7b7db482ea31763 100644 (file)
@@ -16,3 +16,11 @@ cifs-improve-readdir-verbosity.patch
 cxgb4-notify-up-to-route-ctrlq-compl-to-rdma-rspq.patch
 hid-add-quirk-for-dell-pixart-oem-mouse.patch
 signal-only-reschedule-timers-on-signals-timers-have-sent.patch
+powerpc-kprobes-pause-function_graph-tracing-during-jprobes-handling.patch
+powerpc-64s-handle-data-breakpoints-in-radix-mode.patch
+input-i8042-add-fujitsu-lifebook-ah544-to-notimeout-list.patch
+brcmfmac-add-parameter-to-pass-error-code-in-firmware-callback.patch
+brcmfmac-use-firmware-callback-upon-failure-to-load.patch
+brcmfmac-unbind-all-devices-upon-failure-in-firmware-callback.patch
+time-fix-clock-read-clock-race-around-clocksource-changes.patch
+time-fix-clock_monotonic_raw-sub-nanosecond-accounting.patch
diff --git a/queue-4.9/time-fix-clock-read-clock-race-around-clocksource-changes.patch b/queue-4.9/time-fix-clock-read-clock-race-around-clocksource-changes.patch
new file mode 100644 (file)
index 0000000..d7e22e3
--- /dev/null
@@ -0,0 +1,225 @@
+From ceea5e3771ed2378668455fa21861bead7504df5 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Thu, 8 Jun 2017 16:44:20 -0700
+Subject: time: Fix clock->read(clock) race around clocksource changes
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit ceea5e3771ed2378668455fa21861bead7504df5 upstream.
+
+In tests, which excercise switching of clocksources, a NULL
+pointer dereference can be observed on AMR64 platforms in the
+clocksource read() function:
+
+u64 clocksource_mmio_readl_down(struct clocksource *c)
+{
+       return ~(u64)readl_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
+}
+
+This is called from the core timekeeping code via:
+
+       cycle_now = tkr->read(tkr->clock);
+
+tkr->read is the cached tkr->clock->read() function pointer.
+When the clocksource is changed then tkr->clock and tkr->read
+are updated sequentially. The code above results in a sequential
+load operation of tkr->read and tkr->clock as well.
+
+If the store to tkr->clock hits between the loads of tkr->read
+and tkr->clock, then the old read() function is called with the
+new clock pointer. As a consequence the read() function
+dereferences a different data structure and the resulting 'reg'
+pointer can point anywhere including NULL.
+
+This problem was introduced when the timekeeping code was
+switched over to use struct tk_read_base. Before that, it was
+theoretically possible as well when the compiler decided to
+reload clock in the code sequence:
+
+     now = tk->clock->read(tk->clock);
+
+Add a helper function which avoids the issue by reading
+tk_read_base->clock once into a local variable clk and then issue
+the read function via clk->read(clk). This guarantees that the
+read() function always gets the proper clocksource pointer handed
+in.
+
+Since there is now no use for the tkr.read pointer, this patch
+also removes it, and to address stopping the fast timekeeper
+during suspend/resume, it introduces a dummy clocksource to use
+rather then just a dummy read function.
+
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: Prarit Bhargava <prarit@redhat.com>
+Cc: Richard Cochran <richardcochran@gmail.com>
+Cc: Stephen Boyd <stephen.boyd@linaro.org>
+Cc: Miroslav Lichvar <mlichvar@redhat.com>
+Cc: Daniel Mentz <danielmentz@google.com>
+Link: http://lkml.kernel.org/r/1496965462-20003-2-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/timekeeper_internal.h |    1 
+ kernel/time/timekeeping.c           |   52 ++++++++++++++++++++++++------------
+ 2 files changed, 36 insertions(+), 17 deletions(-)
+
+--- a/include/linux/timekeeper_internal.h
++++ b/include/linux/timekeeper_internal.h
+@@ -29,7 +29,6 @@
+  */
+ struct tk_read_base {
+       struct clocksource      *clock;
+-      cycle_t                 (*read)(struct clocksource *cs);
+       cycle_t                 mask;
+       cycle_t                 cycle_last;
+       u32                     mult;
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -116,6 +116,26 @@ static inline void tk_update_sleep_time(
+       tk->offs_boot = ktime_add(tk->offs_boot, delta);
+ }
++/*
++ * tk_clock_read - atomic clocksource read() helper
++ *
++ * This helper is necessary to use in the read paths because, while the
++ * seqlock ensures we don't return a bad value while structures are updated,
++ * it doesn't protect from potential crashes. There is the possibility that
++ * the tkr's clocksource may change between the read reference, and the
++ * clock reference passed to the read function.  This can cause crashes if
++ * the wrong clocksource is passed to the wrong read function.
++ * This isn't necessary to use when holding the timekeeper_lock or doing
++ * a read of the fast-timekeeper tkrs (which is protected by its own locking
++ * and update logic).
++ */
++static inline u64 tk_clock_read(struct tk_read_base *tkr)
++{
++      struct clocksource *clock = READ_ONCE(tkr->clock);
++
++      return clock->read(clock);
++}
++
+ #ifdef CONFIG_DEBUG_TIMEKEEPING
+ #define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */
+@@ -173,7 +193,7 @@ static inline cycle_t timekeeping_get_de
+        */
+       do {
+               seq = read_seqcount_begin(&tk_core.seq);
+-              now = tkr->read(tkr->clock);
++              now = tk_clock_read(tkr);
+               last = tkr->cycle_last;
+               mask = tkr->mask;
+               max = tkr->clock->max_cycles;
+@@ -207,7 +227,7 @@ static inline cycle_t timekeeping_get_de
+       cycle_t cycle_now, delta;
+       /* read clocksource */
+-      cycle_now = tkr->read(tkr->clock);
++      cycle_now = tk_clock_read(tkr);
+       /* calculate the delta since the last update_wall_time */
+       delta = clocksource_delta(cycle_now, tkr->cycle_last, tkr->mask);
+@@ -236,12 +256,10 @@ static void tk_setup_internals(struct ti
+       ++tk->cs_was_changed_seq;
+       old_clock = tk->tkr_mono.clock;
+       tk->tkr_mono.clock = clock;
+-      tk->tkr_mono.read = clock->read;
+       tk->tkr_mono.mask = clock->mask;
+-      tk->tkr_mono.cycle_last = tk->tkr_mono.read(clock);
++      tk->tkr_mono.cycle_last = tk_clock_read(&tk->tkr_mono);
+       tk->tkr_raw.clock = clock;
+-      tk->tkr_raw.read = clock->read;
+       tk->tkr_raw.mask = clock->mask;
+       tk->tkr_raw.cycle_last = tk->tkr_mono.cycle_last;
+@@ -405,7 +423,7 @@ static __always_inline u64 __ktime_get_f
+               now += timekeeping_delta_to_ns(tkr,
+                               clocksource_delta(
+-                                      tkr->read(tkr->clock),
++                                      tk_clock_read(tkr),
+                                       tkr->cycle_last,
+                                       tkr->mask));
+       } while (read_seqcount_retry(&tkf->seq, seq));
+@@ -433,6 +451,10 @@ static cycle_t dummy_clock_read(struct c
+       return cycles_at_suspend;
+ }
++static struct clocksource dummy_clock = {
++      .read = dummy_clock_read,
++};
++
+ /**
+  * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource.
+  * @tk: Timekeeper to snapshot.
+@@ -449,13 +471,13 @@ static void halt_fast_timekeeper(struct
+       struct tk_read_base *tkr = &tk->tkr_mono;
+       memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy));
+-      cycles_at_suspend = tkr->read(tkr->clock);
+-      tkr_dummy.read = dummy_clock_read;
++      cycles_at_suspend = tk_clock_read(tkr);
++      tkr_dummy.clock = &dummy_clock;
+       update_fast_timekeeper(&tkr_dummy, &tk_fast_mono);
+       tkr = &tk->tkr_raw;
+       memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy));
+-      tkr_dummy.read = dummy_clock_read;
++      tkr_dummy.clock = &dummy_clock;
+       update_fast_timekeeper(&tkr_dummy, &tk_fast_raw);
+ }
+@@ -621,11 +643,10 @@ static void timekeeping_update(struct ti
+  */
+ static void timekeeping_forward_now(struct timekeeper *tk)
+ {
+-      struct clocksource *clock = tk->tkr_mono.clock;
+       cycle_t cycle_now, delta;
+       s64 nsec;
+-      cycle_now = tk->tkr_mono.read(clock);
++      cycle_now = tk_clock_read(&tk->tkr_mono);
+       delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
+       tk->tkr_mono.cycle_last = cycle_now;
+       tk->tkr_raw.cycle_last  = cycle_now;
+@@ -901,8 +922,7 @@ void ktime_get_snapshot(struct system_ti
+       do {
+               seq = read_seqcount_begin(&tk_core.seq);
+-
+-              now = tk->tkr_mono.read(tk->tkr_mono.clock);
++              now = tk_clock_read(&tk->tkr_mono);
+               systime_snapshot->cs_was_changed_seq = tk->cs_was_changed_seq;
+               systime_snapshot->clock_was_set_seq = tk->clock_was_set_seq;
+               base_real = ktime_add(tk->tkr_mono.base,
+@@ -1081,7 +1101,7 @@ int get_device_system_crosststamp(int (*
+                * Check whether the system counter value provided by the
+                * device driver is on the current timekeeping interval.
+                */
+-              now = tk->tkr_mono.read(tk->tkr_mono.clock);
++              now = tk_clock_read(&tk->tkr_mono);
+               interval_start = tk->tkr_mono.cycle_last;
+               if (!cycle_between(interval_start, cycles, now)) {
+                       clock_was_set_seq = tk->clock_was_set_seq;
+@@ -1639,7 +1659,7 @@ void timekeeping_resume(void)
+        * The less preferred source will only be tried if there is no better
+        * usable source. The rtc part is handled separately in rtc core code.
+        */
+-      cycle_now = tk->tkr_mono.read(clock);
++      cycle_now = tk_clock_read(&tk->tkr_mono);
+       if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) &&
+               cycle_now > tk->tkr_mono.cycle_last) {
+               u64 num, max = ULLONG_MAX;
+@@ -2057,7 +2077,7 @@ void update_wall_time(void)
+ #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+       offset = real_tk->cycle_interval;
+ #else
+-      offset = clocksource_delta(tk->tkr_mono.read(tk->tkr_mono.clock),
++      offset = clocksource_delta(tk_clock_read(&tk->tkr_mono),
+                                  tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
+ #endif
diff --git a/queue-4.9/time-fix-clock_monotonic_raw-sub-nanosecond-accounting.patch b/queue-4.9/time-fix-clock_monotonic_raw-sub-nanosecond-accounting.patch
new file mode 100644 (file)
index 0000000..e299771
--- /dev/null
@@ -0,0 +1,107 @@
+From 3d88d56c5873f6eebe23e05c3da701960146b801 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Thu, 8 Jun 2017 16:44:21 -0700
+Subject: time: Fix CLOCK_MONOTONIC_RAW sub-nanosecond accounting
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit 3d88d56c5873f6eebe23e05c3da701960146b801 upstream.
+
+Due to how the MONOTONIC_RAW accumulation logic was handled,
+there is the potential for a 1ns discontinuity when we do
+accumulations. This small discontinuity has for the most part
+gone un-noticed, but since ARM64 enabled CLOCK_MONOTONIC_RAW
+in their vDSO clock_gettime implementation, we've seen failures
+with the inconsistency-check test in kselftest.
+
+This patch addresses the issue by using the same sub-ns
+accumulation handling that CLOCK_MONOTONIC uses, which avoids
+the issue for in-kernel users.
+
+Since the ARM64 vDSO implementation has its own clock_gettime
+calculation logic, this patch reduces the frequency of errors,
+but failures are still seen. The ARM64 vDSO will need to be
+updated to include the sub-nanosecond xtime_nsec values in its
+calculation for this issue to be completely fixed.
+
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Tested-by: Daniel Mentz <danielmentz@google.com>
+Cc: Prarit Bhargava <prarit@redhat.com>
+Cc: Kevin Brodsky <kevin.brodsky@arm.com>
+Cc: Richard Cochran <richardcochran@gmail.com>
+Cc: Stephen Boyd <stephen.boyd@linaro.org>
+Cc: Will Deacon <will.deacon@arm.com>
+Cc: Miroslav Lichvar <mlichvar@redhat.com>
+Link: http://lkml.kernel.org/r/1496965462-20003-3-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/timekeeper_internal.h |    4 ++--
+ kernel/time/timekeeping.c           |   20 ++++++++++----------
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+--- a/include/linux/timekeeper_internal.h
++++ b/include/linux/timekeeper_internal.h
+@@ -57,7 +57,7 @@ struct tk_read_base {
+  *                    interval.
+  * @xtime_remainder:  Shifted nano seconds left over when rounding
+  *                    @cycle_interval
+- * @raw_interval:     Raw nano seconds accumulated per NTP interval.
++ * @raw_interval:     Shifted raw nano seconds accumulated per NTP interval.
+  * @ntp_error:                Difference between accumulated time and NTP time in ntp
+  *                    shifted nano seconds.
+  * @ntp_error_shift:  Shift conversion between clock shifted nano seconds and
+@@ -99,7 +99,7 @@ struct timekeeper {
+       cycle_t                 cycle_interval;
+       u64                     xtime_interval;
+       s64                     xtime_remainder;
+-      u32                     raw_interval;
++      u64                     raw_interval;
+       /* The ntp_tick_length() value currently being used.
+        * This cached copy ensures we consistently apply the tick
+        * length for an entire tick, as ntp_tick_length may change
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -278,8 +278,7 @@ static void tk_setup_internals(struct ti
+       /* Go back from cycles -> shifted ns */
+       tk->xtime_interval = (u64) interval * clock->mult;
+       tk->xtime_remainder = ntpinterval - tk->xtime_interval;
+-      tk->raw_interval =
+-              ((u64) interval * clock->mult) >> clock->shift;
++      tk->raw_interval = interval * clock->mult;
+        /* if changing clocks, convert xtime_nsec shift units */
+       if (old_clock) {
+@@ -2023,7 +2022,7 @@ static cycle_t logarithmic_accumulation(
+                                               unsigned int *clock_set)
+ {
+       cycle_t interval = tk->cycle_interval << shift;
+-      u64 raw_nsecs;
++      u64 snsec_per_sec;
+       /* If the offset is smaller than a shifted interval, do nothing */
+       if (offset < interval)
+@@ -2038,14 +2037,15 @@ static cycle_t logarithmic_accumulation(
+       *clock_set |= accumulate_nsecs_to_secs(tk);
+       /* Accumulate raw time */
+-      raw_nsecs = (u64)tk->raw_interval << shift;
+-      raw_nsecs += tk->raw_time.tv_nsec;
+-      if (raw_nsecs >= NSEC_PER_SEC) {
+-              u64 raw_secs = raw_nsecs;
+-              raw_nsecs = do_div(raw_secs, NSEC_PER_SEC);
+-              tk->raw_time.tv_sec += raw_secs;
++      tk->tkr_raw.xtime_nsec += (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
++      tk->tkr_raw.xtime_nsec += tk->raw_interval << shift;
++      snsec_per_sec = (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
++      while (tk->tkr_raw.xtime_nsec >= snsec_per_sec) {
++              tk->tkr_raw.xtime_nsec -= snsec_per_sec;
++              tk->raw_time.tv_sec++;
+       }
+-      tk->raw_time.tv_nsec = raw_nsecs;
++      tk->raw_time.tv_nsec = tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift;
++      tk->tkr_raw.xtime_nsec -= (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
+       /* Accumulate error between NTP and clock interval */
+       tk->ntp_error += tk->ntp_tick << shift;