--- /dev/null
+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");
+
--- /dev/null
+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)
--- /dev/null
+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);
+ }
+
--- /dev/null
+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"),
++ },
++ },
+ { }
+ };
+
--- /dev/null
+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
--- /dev/null
+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;
+ }
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
--- /dev/null
+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
+
--- /dev/null
+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;