--- /dev/null
+From cae43683ca240c1c8ad3c4c5cdd421bbf4081a20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2020 15:36:21 -0600
+Subject: ASoC: SOF: core: release resources on errors in probe_continue
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 410e5e55c9c1c9c0d452ac5b9adb37b933a7747e ]
+
+The initial intent of releasing resources in the .remove does not work
+well with HDaudio codecs. If the probe_continue() fails in a work
+queue, e.g. due to missing firmware or authentication issues, we don't
+release any resources, and as a result the kernel oopses during
+suspend operations.
+
+The suggested fix is to release all resources during errors in
+probe_continue(), and use fw_state to track resource allocation
+state, so that .remove does not attempt to release the same
+hardware resources twice. PM operations are also modified so that
+no action is done if DSP resources have been freed due to
+an error at probe.
+
+Reported-by: Takashi Iwai <tiwai@suse.de>
+Co-developed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Bugzilla: http://bugzilla.suse.com/show_bug.cgi?id=1161246
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/20200124213625.30186-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/core.c | 32 +++++++++++---------------------
+ sound/soc/sof/pm.c | 4 ++++
+ 2 files changed, 15 insertions(+), 21 deletions(-)
+
+diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
+index d95026b5f7c60..a06a54f423dd4 100644
+--- a/sound/soc/sof/core.c
++++ b/sound/soc/sof/core.c
+@@ -466,7 +466,6 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
+
+ return 0;
+
+-#if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
+ fw_trace_err:
+ snd_sof_free_trace(sdev);
+ fw_run_err:
+@@ -477,22 +476,10 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
+ snd_sof_free_debug(sdev);
+ dbg_err:
+ snd_sof_remove(sdev);
+-#else
+-
+- /*
+- * when the probe_continue is handled in a work queue, the
+- * probe does not fail so we don't release resources here.
+- * They will be released with an explicit call to
+- * snd_sof_device_remove() when the PCI/ACPI device is removed
+- */
+-
+-fw_trace_err:
+-fw_run_err:
+-fw_load_err:
+-ipc_err:
+-dbg_err:
+
+-#endif
++ /* all resources freed, update state to match */
++ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
++ sdev->first_boot = true;
+
+ return ret;
+ }
+@@ -575,10 +562,12 @@ int snd_sof_device_remove(struct device *dev)
+ if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
+ cancel_work_sync(&sdev->probe_work);
+
+- snd_sof_fw_unload(sdev);
+- snd_sof_ipc_free(sdev);
+- snd_sof_free_debug(sdev);
+- snd_sof_free_trace(sdev);
++ if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) {
++ snd_sof_fw_unload(sdev);
++ snd_sof_ipc_free(sdev);
++ snd_sof_free_debug(sdev);
++ snd_sof_free_trace(sdev);
++ }
+
+ /*
+ * Unregister machine driver. This will unbind the snd_card which
+@@ -594,7 +583,8 @@ int snd_sof_device_remove(struct device *dev)
+ * scheduled on, when they are unloaded. Therefore, the DSP must be
+ * removed only after the topology has been unloaded.
+ */
+- snd_sof_remove(sdev);
++ if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED)
++ snd_sof_remove(sdev);
+
+ /* release firmware */
+ release_firmware(pdata->fw);
+diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
+index ff1ff68e8b26b..bc09cb5f458ba 100644
+--- a/sound/soc/sof/pm.c
++++ b/sound/soc/sof/pm.c
+@@ -269,6 +269,10 @@ static int sof_resume(struct device *dev, bool runtime_resume)
+ if (!sof_ops(sdev)->resume || !sof_ops(sdev)->runtime_resume)
+ return 0;
+
++ /* DSP was never successfully started, nothing to resume */
++ if (sdev->first_boot)
++ return 0;
++
+ /*
+ * if the runtime_resume flag is set, call the runtime_resume routine
+ * or else call the system resume routine
+--
+2.20.1
+
--- /dev/null
+From 067422190d7e145803e7db2dbeddec8cbd2262d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Dec 2019 18:26:09 -0600
+Subject: ASoC: SOF: Introduce state machine for FW boot
+
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+
+[ Upstream commit 6ca5cecbd1c1758666ab79446f19e0e61ed11444 ]
+
+Add a state machine for FW boot to track the
+different stages of FW boot and replace the boot_complete
+field with fw_state field in struct snd_sof_dev.
+This will be used to determine the actions to be performed
+during system suspend.
+
+One of the main motivations for adding this change is the
+fact that errors during the top-level SOF device probe cannot
+be propagated and therefore suspending the SOF device normally
+during system suspend could potentially run into errors.
+For example, with the current flow, if the FW boot failed
+for some reason and the system suspends, the SOF device
+suspend could fail because the CTX_SAVE IPC would be attempted
+even though the FW never really booted successfully causing it
+to time out. Another scenario that the state machine fixes
+is when the runtime suspend for the SOF device fails and
+the DSP is powered down nevertheless, the CTX_SAVE IPC during
+system suspend would timeout because the DSP is already
+powered down.
+
+Reviewed-by: Curtis Malainey <cujomalainey@chromium.org>
+Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
+Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20191218002616.7652-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/core.c | 50 +++++++++++++++++++++++++++++++-
+ sound/soc/sof/intel/hda-loader.c | 1 -
+ sound/soc/sof/intel/hda.c | 4 +--
+ sound/soc/sof/ipc.c | 17 ++++-------
+ sound/soc/sof/loader.c | 19 ++++++++----
+ sound/soc/sof/pm.c | 21 +++++++++++++-
+ sound/soc/sof/sof-priv.h | 11 ++++++-
+ 7 files changed, 99 insertions(+), 24 deletions(-)
+
+diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
+index e770ccbe09963..d95026b5f7c60 100644
+--- a/sound/soc/sof/core.c
++++ b/sound/soc/sof/core.c
+@@ -306,6 +306,46 @@ static int sof_machine_check(struct snd_sof_dev *sdev)
+ #endif
+ }
+
++/*
++ * FW Boot State Transition Diagram
++ *
++ * +-----------------------------------------------------------------------+
++ * | |
++ * ------------------ ------------------ |
++ * | | | | |
++ * | BOOT_FAILED | | READY_FAILED |-------------------------+ |
++ * | | | | | |
++ * ------------------ ------------------ | |
++ * ^ ^ | |
++ * | | | |
++ * (FW Boot Timeout) (FW_READY FAIL) | |
++ * | | | |
++ * | | | |
++ * ------------------ | ------------------ | |
++ * | | | | | | |
++ * | IN_PROGRESS |---------------+------------->| COMPLETE | | |
++ * | | (FW Boot OK) (FW_READY OK) | | | |
++ * ------------------ ------------------ | |
++ * ^ | | |
++ * | | | |
++ * (FW Loading OK) (System Suspend/Runtime Suspend)
++ * | | | |
++ * | | | |
++ * ------------------ ------------------ | | |
++ * | | | |<-----+ | |
++ * | PREPARE | | NOT_STARTED |<---------------------+ |
++ * | | | |<---------------------------+
++ * ------------------ ------------------
++ * | ^ | ^
++ * | | | |
++ * | +-----------------------+ |
++ * | (DSP Probe OK) |
++ * | |
++ * | |
++ * +------------------------------------+
++ * (System Suspend/Runtime Suspend)
++ */
++
+ static int sof_probe_continue(struct snd_sof_dev *sdev)
+ {
+ struct snd_sof_pdata *plat_data = sdev->pdata;
+@@ -321,6 +361,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
+ return ret;
+ }
+
++ sdev->fw_state = SOF_FW_BOOT_PREPARE;
++
+ /* check machine info */
+ ret = sof_machine_check(sdev);
+ if (ret < 0) {
+@@ -360,7 +402,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
+ goto fw_load_err;
+ }
+
+- /* boot the firmware */
++ sdev->fw_state = SOF_FW_BOOT_IN_PROGRESS;
++
++ /*
++ * Boot the firmware. The FW boot status will be modified
++ * in snd_sof_run_firmware() depending on the outcome.
++ */
+ ret = snd_sof_run_firmware(sdev);
+ if (ret < 0) {
+ dev_err(sdev->dev, "error: failed to boot DSP firmware %d\n",
+@@ -479,6 +526,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
+
+ sdev->pdata = plat_data;
+ sdev->first_boot = true;
++ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
+ dev_set_drvdata(dev, sdev);
+
+ /* check all mandatory ops */
+diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
+index bae7ac3581e51..8852184a25690 100644
+--- a/sound/soc/sof/intel/hda-loader.c
++++ b/sound/soc/sof/intel/hda-loader.c
+@@ -295,7 +295,6 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
+
+ /* init for booting wait */
+ init_waitqueue_head(&sdev->boot_wait);
+- sdev->boot_complete = false;
+
+ /* prepare DMA for code loader stream */
+ tag = cl_stream_prepare(sdev, 0x40, stripped_firmware.size,
+diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
+index 91bd88fddac7a..fb17b87b684bf 100644
+--- a/sound/soc/sof/intel/hda.c
++++ b/sound/soc/sof/intel/hda.c
+@@ -168,7 +168,7 @@ void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags)
+ panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
+ HDA_ADSP_ERROR_CODE_SKL + 0x4);
+
+- if (sdev->boot_complete) {
++ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) {
+ hda_dsp_get_registers(sdev, &xoops, &panic_info, stack,
+ HDA_DSP_STACK_DUMP_SIZE);
+ snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
+@@ -195,7 +195,7 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
+ HDA_DSP_SRAM_REG_FW_STATUS);
+ panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP);
+
+- if (sdev->boot_complete) {
++ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) {
+ hda_dsp_get_registers(sdev, &xoops, &panic_info, stack,
+ HDA_DSP_STACK_DUMP_SIZE);
+ snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
+diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
+index 5fdfbaa8c4ed6..dfe429f9e33fb 100644
+--- a/sound/soc/sof/ipc.c
++++ b/sound/soc/sof/ipc.c
+@@ -346,19 +346,12 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
+ break;
+ case SOF_IPC_FW_READY:
+ /* check for FW boot completion */
+- if (!sdev->boot_complete) {
++ if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS) {
+ err = sof_ops(sdev)->fw_ready(sdev, cmd);
+- if (err < 0) {
+- /*
+- * this indicates a mismatch in ABI
+- * between the driver and fw
+- */
+- dev_err(sdev->dev, "error: ABI mismatch %d\n",
+- err);
+- } else {
+- /* firmware boot completed OK */
+- sdev->boot_complete = true;
+- }
++ if (err < 0)
++ sdev->fw_state = SOF_FW_BOOT_READY_FAILED;
++ else
++ sdev->fw_state = SOF_FW_BOOT_COMPLETE;
+
+ /* wake up firmware loader */
+ wake_up(&sdev->boot_wait);
+diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c
+index 432d12bd49379..31847aa3975dc 100644
+--- a/sound/soc/sof/loader.c
++++ b/sound/soc/sof/loader.c
+@@ -512,7 +512,6 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev)
+ int init_core_mask;
+
+ init_waitqueue_head(&sdev->boot_wait);
+- sdev->boot_complete = false;
+
+ /* create read-only fw_version debugfs to store boot version info */
+ if (sdev->first_boot) {
+@@ -544,19 +543,27 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev)
+
+ init_core_mask = ret;
+
+- /* now wait for the DSP to boot */
+- ret = wait_event_timeout(sdev->boot_wait, sdev->boot_complete,
++ /*
++ * now wait for the DSP to boot. There are 3 possible outcomes:
++ * 1. Boot wait times out indicating FW boot failure.
++ * 2. FW boots successfully and fw_ready op succeeds.
++ * 3. FW boots but fw_ready op fails.
++ */
++ ret = wait_event_timeout(sdev->boot_wait,
++ sdev->fw_state > SOF_FW_BOOT_IN_PROGRESS,
+ msecs_to_jiffies(sdev->boot_timeout));
+ if (ret == 0) {
+ dev_err(sdev->dev, "error: firmware boot failure\n");
+ snd_sof_dsp_dbg_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX |
+ SOF_DBG_TEXT | SOF_DBG_PCI);
+- /* after this point FW_READY msg should be ignored */
+- sdev->boot_complete = true;
++ sdev->fw_state = SOF_FW_BOOT_FAILED;
+ return -EIO;
+ }
+
+- dev_info(sdev->dev, "firmware boot complete\n");
++ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE)
++ dev_info(sdev->dev, "firmware boot complete\n");
++ else
++ return -EIO; /* FW boots but fw_ready op failed */
+
+ /* perform post fw run operations */
+ ret = snd_sof_dsp_post_fw_run(sdev);
+diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
+index 0fd5567237a8d..ff1ff68e8b26b 100644
+--- a/sound/soc/sof/pm.c
++++ b/sound/soc/sof/pm.c
+@@ -283,6 +283,8 @@ static int sof_resume(struct device *dev, bool runtime_resume)
+ return ret;
+ }
+
++ sdev->fw_state = SOF_FW_BOOT_PREPARE;
++
+ /* load the firmware */
+ ret = snd_sof_load_firmware(sdev);
+ if (ret < 0) {
+@@ -292,7 +294,12 @@ static int sof_resume(struct device *dev, bool runtime_resume)
+ return ret;
+ }
+
+- /* boot the firmware */
++ sdev->fw_state = SOF_FW_BOOT_IN_PROGRESS;
++
++ /*
++ * Boot the firmware. The FW boot status will be modified
++ * in snd_sof_run_firmware() depending on the outcome.
++ */
+ ret = snd_sof_run_firmware(sdev);
+ if (ret < 0) {
+ dev_err(sdev->dev,
+@@ -341,6 +348,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
+ if (!sof_ops(sdev)->suspend)
+ return 0;
+
++ if (sdev->fw_state != SOF_FW_BOOT_COMPLETE)
++ goto power_down;
++
+ /* release trace */
+ snd_sof_release_trace(sdev);
+
+@@ -378,6 +388,12 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
+ ret);
+ }
+
++power_down:
++
++ /* return if the DSP was not probed successfully */
++ if (sdev->fw_state == SOF_FW_BOOT_NOT_STARTED)
++ return 0;
++
+ /* power down all DSP cores */
+ if (runtime_suspend)
+ ret = snd_sof_dsp_runtime_suspend(sdev);
+@@ -388,6 +404,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
+ "error: failed to power down DSP during suspend %d\n",
+ ret);
+
++ /* reset FW state */
++ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
++
+ return ret;
+ }
+
+diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
+index c7c2c70ee4d04..59cc711e99ff4 100644
+--- a/sound/soc/sof/sof-priv.h
++++ b/sound/soc/sof/sof-priv.h
+@@ -387,6 +387,15 @@ struct snd_sof_dai {
+ struct list_head list; /* list in sdev dai list */
+ };
+
++enum snd_sof_fw_state {
++ SOF_FW_BOOT_NOT_STARTED = 0,
++ SOF_FW_BOOT_PREPARE,
++ SOF_FW_BOOT_IN_PROGRESS,
++ SOF_FW_BOOT_FAILED,
++ SOF_FW_BOOT_READY_FAILED, /* firmware booted but fw_ready op failed */
++ SOF_FW_BOOT_COMPLETE,
++};
++
+ /*
+ * SOF Device Level.
+ */
+@@ -408,7 +417,7 @@ struct snd_sof_dev {
+
+ /* DSP firmware boot */
+ wait_queue_head_t boot_wait;
+- u32 boot_complete;
++ enum snd_sof_fw_state fw_state;
+ u32 first_boot;
+
+ /* work queue in case the probe is implemented in two steps */
+--
+2.20.1
+
--- /dev/null
+From 6112c1ba351c997f1ba2a0f7ab0bc3091f78819d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2020 02:17:57 -0500
+Subject: ftrace: Add comment to why rcu_dereference_sched() is open coded
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+[ Upstream commit 16052dd5bdfa16dbe18d8c1d4cde2ddab9d23177 ]
+
+Because the function graph tracer can execute in sections where RCU is not
+"watching", the rcu_dereference_sched() for the has needs to be open coded.
+This is fine because the RCU "flavor" of the ftrace hash is protected by
+its own RCU handling (it does its own little synchronization on every CPU
+and does not rely on RCU sched).
+
+Acked-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 497defe9ed264..b769638f005c7 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -961,6 +961,11 @@ static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
+
+ preempt_disable_notrace();
+
++ /*
++ * Have to open code "rcu_dereference_sched()" because the
++ * function graph tracer can be called when RCU is not
++ * "watching".
++ */
+ hash = rcu_dereference_protected(ftrace_graph_hash, !preemptible());
+
+ if (ftrace_hash_empty(hash)) {
+@@ -1008,6 +1013,11 @@ static inline int ftrace_graph_notrace_addr(unsigned long addr)
+
+ preempt_disable_notrace();
+
++ /*
++ * Have to open code "rcu_dereference_sched()" because the
++ * function graph tracer can be called when RCU is not
++ * "watching".
++ */
+ notrace_hash = rcu_dereference_protected(ftrace_graph_notrace_hash,
+ !preemptible());
+
+--
+2.20.1
+
--- /dev/null
+From b9e00433bbd09bfa2baf704e02eb3e817d81b36b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2020 09:20:32 -0500
+Subject: ftrace: Protect ftrace_graph_hash with ftrace_sync
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+[ Upstream commit 54a16ff6f2e50775145b210bcd94d62c3c2af117 ]
+
+As function_graph tracer can run when RCU is not "watching", it can not be
+protected by synchronize_rcu() it requires running a task on each CPU before
+it can be freed. Calling schedule_on_each_cpu(ftrace_sync) needs to be used.
+
+Link: https://lore.kernel.org/r/20200205131110.GT2935@paulmck-ThinkPad-P72
+
+Cc: stable@vger.kernel.org
+Fixes: b9b0c831bed26 ("ftrace: Convert graph filter to use hash tables")
+Reported-by: "Paul E. McKenney" <paulmck@kernel.org>
+Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ftrace.c | 11 +++++++++--
+ kernel/trace/trace.h | 2 ++
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index e85668cdd8c73..3581bd96d6eb3 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -5872,8 +5872,15 @@ ftrace_graph_release(struct inode *inode, struct file *file)
+
+ mutex_unlock(&graph_lock);
+
+- /* Wait till all users are no longer using the old hash */
+- synchronize_rcu();
++ /*
++ * We need to do a hard force of sched synchronization.
++ * This is because we use preempt_disable() to do RCU, but
++ * the function tracers can be called where RCU is not watching
++ * (like before user_exit()). We can not rely on the RCU
++ * infrastructure to do the synchronization, thus we must do it
++ * ourselves.
++ */
++ schedule_on_each_cpu(ftrace_sync);
+
+ free_ftrace_hash(old_hash);
+ }
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index b769638f005c7..85f475bb48238 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -965,6 +965,7 @@ static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
+ * Have to open code "rcu_dereference_sched()" because the
+ * function graph tracer can be called when RCU is not
+ * "watching".
++ * Protected with schedule_on_each_cpu(ftrace_sync)
+ */
+ hash = rcu_dereference_protected(ftrace_graph_hash, !preemptible());
+
+@@ -1017,6 +1018,7 @@ static inline int ftrace_graph_notrace_addr(unsigned long addr)
+ * Have to open code "rcu_dereference_sched()" because the
+ * function graph tracer can be called when RCU is not
+ * "watching".
++ * Protected with schedule_on_each_cpu(ftrace_sync)
+ */
+ notrace_hash = rcu_dereference_protected(ftrace_graph_notrace_hash,
+ !preemptible());
+--
+2.20.1
+
dm-thin-metadata-use-pool-locking-at-end-of-dm_pool_metadata_close.patch
dm-thin-fix-use-after-free-in-metadata_pre_commit_callback.patch
dm-fix-potential-for-q-make_request_fn-null-pointer.patch
+asoc-sof-introduce-state-machine-for-fw-boot.patch
+asoc-sof-core-release-resources-on-errors-in-probe_c.patch
+tracing-annotate-ftrace_graph_hash-pointer-with-__rc.patch
+tracing-annotate-ftrace_graph_notrace_hash-pointer-w.patch
+ftrace-add-comment-to-why-rcu_dereference_sched-is-o.patch
+ftrace-protect-ftrace_graph_hash-with-ftrace_sync.patch
--- /dev/null
+From 8a60eca5bebe1cd514473fd7c3e35a517ff188e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Feb 2020 12:57:04 +0530
+Subject: tracing: Annotate ftrace_graph_hash pointer with __rcu
+
+From: Amol Grover <frextrite@gmail.com>
+
+[ Upstream commit 24a9729f831462b1d9d61dc85ecc91c59037243f ]
+
+Fix following instances of sparse error
+kernel/trace/ftrace.c:5664:29: error: incompatible types in comparison
+kernel/trace/ftrace.c:5785:21: error: incompatible types in comparison
+kernel/trace/ftrace.c:5864:36: error: incompatible types in comparison
+kernel/trace/ftrace.c:5866:25: error: incompatible types in comparison
+
+Use rcu_dereference_protected to access the __rcu annotated pointer.
+
+Link: http://lkml.kernel.org/r/20200201072703.17330-1-frextrite@gmail.com
+
+Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Amol Grover <frextrite@gmail.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ftrace.c | 2 +-
+ kernel/trace/trace.h | 9 ++++++---
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 9bf1f2cd515ef..959ded08dc13f 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -5596,7 +5596,7 @@ static const struct file_operations ftrace_notrace_fops = {
+
+ static DEFINE_MUTEX(graph_lock);
+
+-struct ftrace_hash *ftrace_graph_hash = EMPTY_HASH;
++struct ftrace_hash __rcu *ftrace_graph_hash = EMPTY_HASH;
+ struct ftrace_hash *ftrace_graph_notrace_hash = EMPTY_HASH;
+
+ enum graph_filter_type {
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 63bf60f793987..97dad33260208 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -950,22 +950,25 @@ extern void __trace_graph_return(struct trace_array *tr,
+ unsigned long flags, int pc);
+
+ #ifdef CONFIG_DYNAMIC_FTRACE
+-extern struct ftrace_hash *ftrace_graph_hash;
++extern struct ftrace_hash __rcu *ftrace_graph_hash;
+ extern struct ftrace_hash *ftrace_graph_notrace_hash;
+
+ static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
+ {
+ unsigned long addr = trace->func;
+ int ret = 0;
++ struct ftrace_hash *hash;
+
+ preempt_disable_notrace();
+
+- if (ftrace_hash_empty(ftrace_graph_hash)) {
++ hash = rcu_dereference_protected(ftrace_graph_hash, !preemptible());
++
++ if (ftrace_hash_empty(hash)) {
+ ret = 1;
+ goto out;
+ }
+
+- if (ftrace_lookup_ip(ftrace_graph_hash, addr)) {
++ if (ftrace_lookup_ip(hash, addr)) {
+
+ /*
+ * This needs to be cleared on the return functions
+--
+2.20.1
+
--- /dev/null
+From 548bbed7d4f8be54639f23b0892938bb61013285 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2020 11:27:02 +0530
+Subject: tracing: Annotate ftrace_graph_notrace_hash pointer with __rcu
+
+From: Amol Grover <frextrite@gmail.com>
+
+[ Upstream commit fd0e6852c407dd9aefc594f54ddcc21d84803d3b ]
+
+Fix following instances of sparse error
+kernel/trace/ftrace.c:5667:29: error: incompatible types in comparison
+kernel/trace/ftrace.c:5813:21: error: incompatible types in comparison
+kernel/trace/ftrace.c:5868:36: error: incompatible types in comparison
+kernel/trace/ftrace.c:5870:25: error: incompatible types in comparison
+
+Use rcu_dereference_protected to dereference the newly annotated pointer.
+
+Link: http://lkml.kernel.org/r/20200205055701.30195-1-frextrite@gmail.com
+
+Signed-off-by: Amol Grover <frextrite@gmail.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ftrace.c | 2 +-
+ kernel/trace/trace.h | 8 ++++++--
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 959ded08dc13f..e85668cdd8c73 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -5597,7 +5597,7 @@ static const struct file_operations ftrace_notrace_fops = {
+ static DEFINE_MUTEX(graph_lock);
+
+ struct ftrace_hash __rcu *ftrace_graph_hash = EMPTY_HASH;
+-struct ftrace_hash *ftrace_graph_notrace_hash = EMPTY_HASH;
++struct ftrace_hash __rcu *ftrace_graph_notrace_hash = EMPTY_HASH;
+
+ enum graph_filter_type {
+ GRAPH_FILTER_NOTRACE = 0,
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 97dad33260208..497defe9ed264 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -951,7 +951,7 @@ extern void __trace_graph_return(struct trace_array *tr,
+
+ #ifdef CONFIG_DYNAMIC_FTRACE
+ extern struct ftrace_hash __rcu *ftrace_graph_hash;
+-extern struct ftrace_hash *ftrace_graph_notrace_hash;
++extern struct ftrace_hash __rcu *ftrace_graph_notrace_hash;
+
+ static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
+ {
+@@ -1004,10 +1004,14 @@ static inline void ftrace_graph_addr_finish(struct ftrace_graph_ret *trace)
+ static inline int ftrace_graph_notrace_addr(unsigned long addr)
+ {
+ int ret = 0;
++ struct ftrace_hash *notrace_hash;
+
+ preempt_disable_notrace();
+
+- if (ftrace_lookup_ip(ftrace_graph_notrace_hash, addr))
++ notrace_hash = rcu_dereference_protected(ftrace_graph_notrace_hash,
++ !preemptible());
++
++ if (ftrace_lookup_ip(notrace_hash, addr))
+ ret = 1;
+
+ preempt_enable_notrace();
+--
+2.20.1
+