--- /dev/null
+From 0c32706dac1b0a72713184246952ab0f54327c21 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Mon, 2 Aug 2021 17:48:45 +0100
+Subject: arm64: stacktrace: avoid tracing arch_stack_walk()
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit 0c32706dac1b0a72713184246952ab0f54327c21 upstream.
+
+When the function_graph tracer is in use, arch_stack_walk() may unwind
+the stack incorrectly, erroneously reporting itself, missing the final
+entry which is being traced, and reporting all traced entries between
+these off-by-one from where they should be.
+
+When ftrace hooks a function return, the original return address is
+saved to the fgraph ret_stack, and the return address in the LR (or the
+function's frame record) is replaced with `return_to_handler`.
+
+When arm64's unwinder encounter frames returning to `return_to_handler`,
+it finds the associated original return address from the fgraph ret
+stack, assuming the most recent `ret_to_hander` entry on the stack
+corresponds to the most recent entry in the fgraph ret stack, and so on.
+
+When arch_stack_walk() is used to dump the current task's stack, it
+starts from the caller of arch_stack_walk(). However, arch_stack_walk()
+can be traced, and so may push an entry on to the fgraph ret stack,
+leaving the fgraph ret stack offset by one from the expected position.
+
+This can be seen when dumping the stack via /proc/self/stack, where
+enabling the graph tracer results in an unexpected
+`stack_trace_save_tsk` entry at the start of the trace, and `el0_svc`
+missing form the end of the trace.
+
+This patch fixes this by marking arch_stack_walk() as notrace, as we do
+for all other functions on the path to ftrace_graph_get_ret_stack().
+While a few helper functions are not marked notrace, their calls/returns
+are balanced, and will have no observable effect when examining the
+fgraph ret stack.
+
+It is possible for an exeption boundary to cause a similar offset if the
+return address of the interrupted context was in the LR. Fixing those
+cases will require some more substantial rework, and is left for
+subsequent patches.
+
+Before:
+
+| # cat /proc/self/stack
+| [<0>] proc_pid_stack+0xc4/0x140
+| [<0>] proc_single_show+0x6c/0x120
+| [<0>] seq_read_iter+0x240/0x4e0
+| [<0>] seq_read+0xe8/0x140
+| [<0>] vfs_read+0xb8/0x1e4
+| [<0>] ksys_read+0x74/0x100
+| [<0>] __arm64_sys_read+0x28/0x3c
+| [<0>] invoke_syscall+0x50/0x120
+| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
+| [<0>] do_el0_svc+0x30/0x9c
+| [<0>] el0_svc+0x2c/0x54
+| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
+| [<0>] el0t_64_sync+0x198/0x19c
+| # echo function_graph > /sys/kernel/tracing/current_tracer
+| # cat /proc/self/stack
+| [<0>] stack_trace_save_tsk+0xa4/0x110
+| [<0>] proc_pid_stack+0xc4/0x140
+| [<0>] proc_single_show+0x6c/0x120
+| [<0>] seq_read_iter+0x240/0x4e0
+| [<0>] seq_read+0xe8/0x140
+| [<0>] vfs_read+0xb8/0x1e4
+| [<0>] ksys_read+0x74/0x100
+| [<0>] __arm64_sys_read+0x28/0x3c
+| [<0>] invoke_syscall+0x50/0x120
+| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
+| [<0>] do_el0_svc+0x30/0x9c
+| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
+| [<0>] el0t_64_sync+0x198/0x19c
+
+After:
+
+| # cat /proc/self/stack
+| [<0>] proc_pid_stack+0xc4/0x140
+| [<0>] proc_single_show+0x6c/0x120
+| [<0>] seq_read_iter+0x240/0x4e0
+| [<0>] seq_read+0xe8/0x140
+| [<0>] vfs_read+0xb8/0x1e4
+| [<0>] ksys_read+0x74/0x100
+| [<0>] __arm64_sys_read+0x28/0x3c
+| [<0>] invoke_syscall+0x50/0x120
+| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
+| [<0>] do_el0_svc+0x30/0x9c
+| [<0>] el0_svc+0x2c/0x54
+| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
+| [<0>] el0t_64_sync+0x198/0x19c
+| # echo function_graph > /sys/kernel/tracing/current_tracer
+| # cat /proc/self/stack
+| [<0>] proc_pid_stack+0xc4/0x140
+| [<0>] proc_single_show+0x6c/0x120
+| [<0>] seq_read_iter+0x240/0x4e0
+| [<0>] seq_read+0xe8/0x140
+| [<0>] vfs_read+0xb8/0x1e4
+| [<0>] ksys_read+0x74/0x100
+| [<0>] __arm64_sys_read+0x28/0x3c
+| [<0>] invoke_syscall+0x50/0x120
+| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
+| [<0>] do_el0_svc+0x30/0x9c
+| [<0>] el0_svc+0x2c/0x54
+| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
+| [<0>] el0t_64_sync+0x198/0x19c
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Reviwed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20210802164845.45506-3-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/stacktrace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/kernel/stacktrace.c
++++ b/arch/arm64/kernel/stacktrace.c
+@@ -199,7 +199,7 @@ void show_stack(struct task_struct *tsk,
+
+ #ifdef CONFIG_STACKTRACE
+
+-noinline void arch_stack_walk(stack_trace_consume_fn consume_entry,
++noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
+ void *cookie, struct task_struct *task,
+ struct pt_regs *regs)
+ {
--- /dev/null
+From f828b0bcacef189edbd247e9f48864fc36bfbe33 Mon Sep 17 00:00:00 2001
+From: Brian Norris <briannorris@chromium.org>
+Date: Fri, 30 Jul 2021 19:59:50 -0700
+Subject: clk: fix leak on devm_clk_bulk_get_all() unwind
+
+From: Brian Norris <briannorris@chromium.org>
+
+commit f828b0bcacef189edbd247e9f48864fc36bfbe33 upstream.
+
+clk_bulk_get_all() allocates an array of struct clk_bulk data for us
+(unlike clk_bulk_get()), so we need to free it. Let's use the
+clk_bulk_put_all() helper.
+
+kmemleak complains, on an RK3399 Gru/Kevin system:
+
+unreferenced object 0xffffff80045def00 (size 128):
+ comm "swapper/0", pid 1, jiffies 4294667682 (age 86.394s)
+ hex dump (first 32 bytes):
+ 44 32 60 fe fe ff ff ff 00 00 00 00 00 00 00 00 D2`.............
+ 48 32 60 fe fe ff ff ff 00 00 00 00 00 00 00 00 H2`.............
+ backtrace:
+ [<00000000742860d6>] __kmalloc+0x22c/0x39c
+ [<00000000b0493f2c>] clk_bulk_get_all+0x64/0x188
+ [<00000000325f5900>] devm_clk_bulk_get_all+0x58/0xa8
+ [<00000000175b9bc5>] dwc3_probe+0x8ac/0xb5c
+ [<000000009169e2f9>] platform_drv_probe+0x9c/0xbc
+ [<000000005c51e2ee>] really_probe+0x13c/0x378
+ [<00000000c47b1f24>] driver_probe_device+0x84/0xc0
+ [<00000000f870fcfb>] __device_attach_driver+0x94/0xb0
+ [<000000004d1b92ae>] bus_for_each_drv+0x8c/0xd8
+ [<00000000481d60c3>] __device_attach+0xc4/0x150
+ [<00000000a163bd36>] device_initial_probe+0x1c/0x28
+ [<00000000accb6bad>] bus_probe_device+0x3c/0x9c
+ [<000000001a199f89>] device_add+0x218/0x3cc
+ [<000000001bd84952>] of_device_add+0x40/0x50
+ [<000000009c658c29>] of_platform_device_create_pdata+0xac/0x100
+ [<0000000021c69ba4>] of_platform_bus_create+0x190/0x224
+
+Fixes: f08c2e2865f6 ("clk: add managed version of clk_bulk_get_all")
+Cc: Dong Aisheng <aisheng.dong@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Link: https://lore.kernel.org/r/20210731025950.2238582-1-briannorris@chromium.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clk/clk-devres.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/clk-devres.c
++++ b/drivers/clk/clk-devres.c
+@@ -92,13 +92,20 @@ int __must_check devm_clk_bulk_get_optio
+ }
+ EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional);
+
++static void devm_clk_bulk_release_all(struct device *dev, void *res)
++{
++ struct clk_bulk_devres *devres = res;
++
++ clk_bulk_put_all(devres->num_clks, devres->clks);
++}
++
+ int __must_check devm_clk_bulk_get_all(struct device *dev,
+ struct clk_bulk_data **clks)
+ {
+ struct clk_bulk_devres *devres;
+ int ret;
+
+- devres = devres_alloc(devm_clk_bulk_release,
++ devres = devres_alloc(devm_clk_bulk_release_all,
+ sizeof(*devres), GFP_KERNEL);
+ if (!devres)
+ return -ENOMEM;
--- /dev/null
+From b5c10dd04b7418793517e3286cde5c04759a86de Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+Date: Mon, 14 Jun 2021 17:33:13 -0500
+Subject: optee: Clear stale cache entries during initialization
+
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+
+commit b5c10dd04b7418793517e3286cde5c04759a86de upstream.
+
+The shm cache could contain invalid addresses if
+optee_disable_shm_cache() was not called from the .shutdown hook of the
+previous kernel before a kexec. These addresses could be unmapped or
+they could point to mapped but unintended locations in memory.
+
+Clear the shared memory cache, while being careful to not translate the
+addresses returned from OPTEE_SMC_DISABLE_SHM_CACHE, during driver
+initialization. Once all pre-cache shm objects are removed, proceed with
+enabling the cache so that we know that we can handle cached shm objects
+with confidence later in the .shutdown hook.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
+Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tee/optee/call.c | 36 +++++++++++++++++++++++++++++++++---
+ drivers/tee/optee/core.c | 9 +++++++++
+ drivers/tee/optee/optee_private.h | 1 +
+ 3 files changed, 43 insertions(+), 3 deletions(-)
+
+--- a/drivers/tee/optee/call.c
++++ b/drivers/tee/optee/call.c
+@@ -413,11 +413,13 @@ void optee_enable_shm_cache(struct optee
+ }
+
+ /**
+- * optee_disable_shm_cache() - Disables caching of some shared memory allocation
+- * in OP-TEE
++ * __optee_disable_shm_cache() - Disables caching of some shared memory
++ * allocation in OP-TEE
+ * @optee: main service struct
++ * @is_mapped: true if the cached shared memory addresses were mapped by this
++ * kernel, are safe to dereference, and should be freed
+ */
+-void optee_disable_shm_cache(struct optee *optee)
++static void __optee_disable_shm_cache(struct optee *optee, bool is_mapped)
+ {
+ struct optee_call_waiter w;
+
+@@ -436,6 +438,13 @@ void optee_disable_shm_cache(struct opte
+ if (res.result.status == OPTEE_SMC_RETURN_OK) {
+ struct tee_shm *shm;
+
++ /*
++ * Shared memory references that were not mapped by
++ * this kernel must be ignored to prevent a crash.
++ */
++ if (!is_mapped)
++ continue;
++
+ shm = reg_pair_to_ptr(res.result.shm_upper32,
+ res.result.shm_lower32);
+ tee_shm_free(shm);
+@@ -446,6 +455,27 @@ void optee_disable_shm_cache(struct opte
+ optee_cq_wait_final(&optee->call_queue, &w);
+ }
+
++/**
++ * optee_disable_shm_cache() - Disables caching of mapped shared memory
++ * allocations in OP-TEE
++ * @optee: main service struct
++ */
++void optee_disable_shm_cache(struct optee *optee)
++{
++ return __optee_disable_shm_cache(optee, true);
++}
++
++/**
++ * optee_disable_unmapped_shm_cache() - Disables caching of shared memory
++ * allocations in OP-TEE which are not
++ * currently mapped
++ * @optee: main service struct
++ */
++void optee_disable_unmapped_shm_cache(struct optee *optee)
++{
++ return __optee_disable_shm_cache(optee, false);
++}
++
+ #define PAGELIST_ENTRIES_PER_PAGE \
+ ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)
+
+--- a/drivers/tee/optee/core.c
++++ b/drivers/tee/optee/core.c
+@@ -686,6 +686,15 @@ static int optee_probe(struct platform_d
+ optee->memremaped_shm = memremaped_shm;
+ optee->pool = pool;
+
++ /*
++ * Ensure that there are no pre-existing shm objects before enabling
++ * the shm cache so that there's no chance of receiving an invalid
++ * address during shutdown. This could occur, for example, if we're
++ * kexec booting from an older kernel that did not properly cleanup the
++ * shm cache.
++ */
++ optee_disable_unmapped_shm_cache(optee);
++
+ optee_enable_shm_cache(optee);
+
+ if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+--- a/drivers/tee/optee/optee_private.h
++++ b/drivers/tee/optee/optee_private.h
+@@ -159,6 +159,7 @@ int optee_cancel_req(struct tee_context
+
+ void optee_enable_shm_cache(struct optee *optee);
+ void optee_disable_shm_cache(struct optee *optee);
++void optee_disable_unmapped_shm_cache(struct optee *optee);
+
+ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
+ struct page **pages, size_t num_pages,
--- /dev/null
+From ec185dd3ab257dc2a60953fdf1b6622f524cc5b7 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+Date: Mon, 14 Jun 2021 17:33:10 -0500
+Subject: optee: Fix memory leak when failing to register shm pages
+
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+
+commit ec185dd3ab257dc2a60953fdf1b6622f524cc5b7 upstream.
+
+Free the previously allocated pages when we encounter an error condition
+while attempting to register the pages with the secure world.
+
+Fixes: a249dd200d03 ("tee: optee: Fix dynamic shm pool allocations")
+Fixes: 5a769f6ff439 ("optee: Fix multi page dynamic shm pool alloc")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
+Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tee/optee/shm_pool.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/tee/optee/shm_pool.c
++++ b/drivers/tee/optee/shm_pool.c
+@@ -32,8 +32,10 @@ static int pool_op_alloc(struct tee_shm_
+ struct page **pages;
+
+ pages = kcalloc(nr_pages, sizeof(pages), GFP_KERNEL);
+- if (!pages)
+- return -ENOMEM;
++ if (!pages) {
++ rc = -ENOMEM;
++ goto err;
++ }
+
+ for (i = 0; i < nr_pages; i++) {
+ pages[i] = page;
+@@ -44,8 +46,14 @@ static int pool_op_alloc(struct tee_shm_
+ rc = optee_shm_register(shm->ctx, shm, pages, nr_pages,
+ (unsigned long)shm->kaddr);
+ kfree(pages);
++ if (rc)
++ goto err;
+ }
+
++ return 0;
++
++err:
++ __free_pages(page, order);
+ return rc;
+ }
+
--- /dev/null
+From f25889f93184db8b07a543cc2bbbb9a8fcaf4333 Mon Sep 17 00:00:00 2001
+From: Allen Pais <apais@linux.microsoft.com>
+Date: Mon, 14 Jun 2021 17:33:12 -0500
+Subject: optee: fix tee out of memory failure seen during kexec reboot
+
+From: Allen Pais <apais@linux.microsoft.com>
+
+commit f25889f93184db8b07a543cc2bbbb9a8fcaf4333 upstream.
+
+The following out of memory errors are seen on kexec reboot
+from the optee core.
+
+[ 0.368428] tee_bnxt_fw optee-clnt0: tee_shm_alloc failed
+[ 0.368461] tee_bnxt_fw: probe of optee-clnt0 failed with error -22
+
+tee_shm_release() is not invoked on dma shm buffer.
+
+Implement .shutdown() method to handle the release of the buffers
+correctly.
+
+More info:
+https://github.com/OP-TEE/optee_os/issues/3637
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Allen Pais <apais@linux.microsoft.com>
+Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com>
+Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tee/optee/core.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/tee/optee/core.c
++++ b/drivers/tee/optee/core.c
+@@ -573,6 +573,13 @@ static optee_invoke_fn *get_invoke_func(
+ return ERR_PTR(-EINVAL);
+ }
+
++/* optee_remove - Device Removal Routine
++ * @pdev: platform device information struct
++ *
++ * optee_remove is called by platform subsystem to alert the driver
++ * that it should release the device
++ */
++
+ static int optee_remove(struct platform_device *pdev)
+ {
+ struct optee *optee = platform_get_drvdata(pdev);
+@@ -603,6 +610,18 @@ static int optee_remove(struct platform_
+ return 0;
+ }
+
++/* optee_shutdown - Device Removal Routine
++ * @pdev: platform device information struct
++ *
++ * platform_shutdown is called by the platform subsystem to alert
++ * the driver that a shutdown, reboot, or kexec is happening and
++ * device must be disabled.
++ */
++static void optee_shutdown(struct platform_device *pdev)
++{
++ optee_disable_shm_cache(platform_get_drvdata(pdev));
++}
++
+ static int optee_probe(struct platform_device *pdev)
+ {
+ optee_invoke_fn *invoke_fn;
+@@ -748,6 +767,7 @@ MODULE_DEVICE_TABLE(of, optee_dt_match);
+ static struct platform_driver optee_driver = {
+ .probe = optee_probe,
+ .remove = optee_remove,
++ .shutdown = optee_shutdown,
+ .driver = {
+ .name = "optee",
+ .of_match_table = optee_dt_match,
--- /dev/null
+From adf752af454e91e123e85e3784972d166837af73 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+Date: Mon, 14 Jun 2021 17:33:11 -0500
+Subject: optee: Refuse to load the driver under the kdump kernel
+
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+
+commit adf752af454e91e123e85e3784972d166837af73 upstream.
+
+Fix a hung task issue, seen when booting the kdump kernel, that is
+caused by all of the secure world threads being in a permanent suspended
+state:
+
+ INFO: task swapper/0:1 blocked for more than 120 seconds.
+ Not tainted 5.4.83 #1
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ swapper/0 D 0 1 0 0x00000028
+ Call trace:
+ __switch_to+0xc8/0x118
+ __schedule+0x2e0/0x700
+ schedule+0x38/0xb8
+ schedule_timeout+0x258/0x388
+ wait_for_completion+0x16c/0x4b8
+ optee_cq_wait_for_completion+0x28/0xa8
+ optee_disable_shm_cache+0xb8/0xf8
+ optee_probe+0x560/0x61c
+ platform_drv_probe+0x58/0xa8
+ really_probe+0xe0/0x338
+ driver_probe_device+0x5c/0xf0
+ device_driver_attach+0x74/0x80
+ __driver_attach+0x64/0xe0
+ bus_for_each_dev+0x84/0xd8
+ driver_attach+0x30/0x40
+ bus_add_driver+0x188/0x1e8
+ driver_register+0x64/0x110
+ __platform_driver_register+0x54/0x60
+ optee_driver_init+0x20/0x28
+ do_one_initcall+0x54/0x24c
+ kernel_init_freeable+0x1e8/0x2c0
+ kernel_init+0x18/0x118
+ ret_from_fork+0x10/0x18
+
+The invoke_fn hook returned OPTEE_SMC_RETURN_ETHREAD_LIMIT, indicating
+that the secure world threads were all in a suspended state at the time
+of the kernel crash. This intermittently prevented the kdump kernel from
+booting, resulting in a failure to collect the kernel dump.
+
+Make kernel dump collection more reliable on systems utilizing OP-TEE by
+refusing to load the driver under the kdump kernel.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
+Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tee/optee/core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/tee/optee/core.c
++++ b/drivers/tee/optee/core.c
+@@ -6,6 +6,7 @@
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/arm-smccc.h>
++#include <linux/crash_dump.h>
+ #include <linux/errno.h>
+ #include <linux/io.h>
+ #include <linux/module.h>
+@@ -612,6 +613,16 @@ static int optee_probe(struct platform_d
+ u32 sec_caps;
+ int rc;
+
++ /*
++ * The kernel may have crashed at the same time that all available
++ * secure world threads were suspended and we cannot reschedule the
++ * suspended threads without access to the crashed kernel's wait_queue.
++ * Therefore, we cannot reliably initialize the OP-TEE driver in the
++ * kdump kernel.
++ */
++ if (is_kdump_kernel())
++ return -ENODEV;
++
+ invoke_fn = get_invoke_func(&pdev->dev);
+ if (IS_ERR(invoke_fn))
+ return PTR_ERR(invoke_fn);
--- /dev/null
+From 1c0cec64a7cc545eb49f374a43e9f7190a14defa Mon Sep 17 00:00:00 2001
+From: Hui Su <suhui@zeku.com>
+Date: Fri, 11 Jun 2021 10:21:07 +0800
+Subject: scripts/tracing: fix the bug that can't parse raw_trace_func
+
+From: Hui Su <suhui@zeku.com>
+
+commit 1c0cec64a7cc545eb49f374a43e9f7190a14defa upstream.
+
+Since commit 77271ce4b2c0 ("tracing: Add irq, preempt-count and need resched info
+to default trace output"), the default trace output format has been changed to:
+ <idle>-0 [009] d.h. 22420.068695: _raw_spin_lock_irqsave <-hrtimer_interrupt
+ <idle>-0 [000] ..s. 22420.068695: _nohz_idle_balance <-run_rebalance_domains
+ <idle>-0 [011] d.h. 22420.068695: account_process_tick <-update_process_times
+
+origin trace output format:(before v3.2.0)
+ # tracer: nop
+ #
+ # TASK-PID CPU# TIMESTAMP FUNCTION
+ # | | | | |
+ migration/0-6 [000] 50.025810: rcu_note_context_switch <-__schedule
+ migration/0-6 [000] 50.025812: trace_rcu_utilization <-rcu_note_context_switch
+ migration/0-6 [000] 50.025813: rcu_sched_qs <-rcu_note_context_switch
+ migration/0-6 [000] 50.025815: rcu_preempt_qs <-rcu_note_context_switch
+ migration/0-6 [000] 50.025817: trace_rcu_utilization <-rcu_note_context_switch
+ migration/0-6 [000] 50.025818: debug_lockdep_rcu_enabled <-__schedule
+ migration/0-6 [000] 50.025820: debug_lockdep_rcu_enabled <-__schedule
+
+The draw_functrace.py(introduced in v2.6.28) can't parse the new version format trace_func,
+So we need modify draw_functrace.py to adapt the new version trace output format.
+
+Link: https://lkml.kernel.org/r/20210611022107.608787-1-suhui@zeku.com
+
+Cc: stable@vger.kernel.org
+Fixes: 77271ce4b2c0 tracing: Add irq, preempt-count and need resched info to default trace output
+Signed-off-by: Hui Su <suhui@zeku.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/tracing/draw_functrace.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/scripts/tracing/draw_functrace.py
++++ b/scripts/tracing/draw_functrace.py
+@@ -17,7 +17,7 @@ Usage:
+ $ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func
+ Wait some times but not too much, the script is a bit slow.
+ Break the pipe (Ctrl + Z)
+- $ scripts/draw_functrace.py < raw_trace_func > draw_functrace
++ $ scripts/tracing/draw_functrace.py < ~/raw_trace_func > draw_functrace
+ Then you have your drawn trace in draw_functrace
+ """
+
+@@ -103,10 +103,10 @@ def parseLine(line):
+ line = line.strip()
+ if line.startswith("#"):
+ raise CommentLineException
+- m = re.match("[^]]+?\\] +([0-9.]+): (\\w+) <-(\\w+)", line)
++ m = re.match("[^]]+?\\] +([a-z.]+) +([0-9.]+): (\\w+) <-(\\w+)", line)
+ if m is None:
+ raise BrokenLineException
+- return (m.group(1), m.group(2), m.group(3))
++ return (m.group(2), m.group(3), m.group(4))
+
+
+ def main():
usb-host-ohci-at91-suspend-resume-ports-after-before-ohci-accesses.patch
usb-typec-tcpm-keep-other-events-when-receiving-frs-and-sourcing_vbus-events.patch
usb-otg-fsm-fix-hrtimer-list-corruption.patch
+clk-fix-leak-on-devm_clk_bulk_get_all-unwind.patch
+scripts-tracing-fix-the-bug-that-can-t-parse-raw_trace_func.patch
+tracing-histogram-give-calculation-hist_fields-a-size.patch
+tracing-reject-string-operand-in-the-histogram-expression.patch
+tracing-fix-null-pointer-dereference-in-start_creating.patch
+tracepoint-static-call-compare-data-on-transition-from-2-1-callees.patch
+tracepoint-fix-static-call-function-vs-data-state-mismatch.patch
+arm64-stacktrace-avoid-tracing-arch_stack_walk.patch
+optee-clear-stale-cache-entries-during-initialization.patch
+tee-add-tee_shm_alloc_kernel_buf.patch
+optee-fix-memory-leak-when-failing-to-register-shm-pages.patch
+optee-refuse-to-load-the-driver-under-the-kdump-kernel.patch
+optee-fix-tee-out-of-memory-failure-seen-during-kexec-reboot.patch
+tpm_ftpm_tee-free-and-unregister-tee-shared-memory-during-kexec.patch
--- /dev/null
+From dc7019b7d0e188d4093b34bd0747ed0d668c63bf Mon Sep 17 00:00:00 2001
+From: Jens Wiklander <jens.wiklander@linaro.org>
+Date: Mon, 14 Jun 2021 17:33:14 -0500
+Subject: tee: add tee_shm_alloc_kernel_buf()
+
+From: Jens Wiklander <jens.wiklander@linaro.org>
+
+commit dc7019b7d0e188d4093b34bd0747ed0d668c63bf upstream.
+
+Adds a new function tee_shm_alloc_kernel_buf() to allocate shared memory
+from a kernel driver. This function can later be made more lightweight
+by unnecessary dma-buf export.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tee/tee_shm.c | 18 ++++++++++++++++++
+ include/linux/tee_drv.h | 1 +
+ 2 files changed, 19 insertions(+)
+
+--- a/drivers/tee/tee_shm.c
++++ b/drivers/tee/tee_shm.c
+@@ -193,6 +193,24 @@ err_dev_put:
+ }
+ EXPORT_SYMBOL_GPL(tee_shm_alloc);
+
++/**
++ * tee_shm_alloc_kernel_buf() - Allocate shared memory for kernel buffer
++ * @ctx: Context that allocates the shared memory
++ * @size: Requested size of shared memory
++ *
++ * The returned memory registered in secure world and is suitable to be
++ * passed as a memory buffer in parameter argument to
++ * tee_client_invoke_func(). The memory allocated is later freed with a
++ * call to tee_shm_free().
++ *
++ * @returns a pointer to 'struct tee_shm'
++ */
++struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size)
++{
++ return tee_shm_alloc(ctx, size, TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
++}
++EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf);
++
+ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
+ size_t length, u32 flags)
+ {
+--- a/include/linux/tee_drv.h
++++ b/include/linux/tee_drv.h
+@@ -332,6 +332,7 @@ void *tee_get_drvdata(struct tee_device
+ * @returns a pointer to 'struct tee_shm'
+ */
+ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags);
++struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);
+
+ /**
+ * tee_shm_register() - Register shared memory buffer
--- /dev/null
+From dfb703ad2a8d366b829818a558337be779746575 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+Date: Mon, 14 Jun 2021 17:33:16 -0500
+Subject: tpm_ftpm_tee: Free and unregister TEE shared memory during kexec
+
+From: Tyler Hicks <tyhicks@linux.microsoft.com>
+
+commit dfb703ad2a8d366b829818a558337be779746575 upstream.
+
+dma-buf backed shared memory cannot be reliably freed and unregistered
+during a kexec operation even when tee_shm_free() is called on the shm
+from a .shutdown hook. The problem occurs because dma_buf_put() calls
+fput() which then uses task_work_add(), with the TWA_RESUME parameter,
+to queue tee_shm_release() to be called before the current task returns
+to user mode. However, the current task never returns to user mode
+before the kexec completes so the memory is never freed nor
+unregistered.
+
+Use tee_shm_alloc_kernel_buf() to avoid dma-buf backed shared memory
+allocation so that tee_shm_free() can directly call tee_shm_release().
+This will ensure that the shm can be freed and unregistered during a
+kexec operation.
+
+Fixes: 09e574831b27 ("tpm/tpm_ftpm_tee: A driver for firmware TPM running inside TEE")
+Fixes: 1760eb689ed6 ("tpm/tpm_ftpm_tee: add shutdown call back")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_ftpm_tee.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/char/tpm/tpm_ftpm_tee.c
++++ b/drivers/char/tpm/tpm_ftpm_tee.c
+@@ -254,11 +254,11 @@ static int ftpm_tee_probe(struct device
+ pvt_data->session = sess_arg.session;
+
+ /* Allocate dynamic shared memory with fTPM TA */
+- pvt_data->shm = tee_shm_alloc(pvt_data->ctx,
+- MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE,
+- TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
++ pvt_data->shm = tee_shm_alloc_kernel_buf(pvt_data->ctx,
++ MAX_COMMAND_SIZE +
++ MAX_RESPONSE_SIZE);
+ if (IS_ERR(pvt_data->shm)) {
+- dev_err(dev, "%s: tee_shm_alloc failed\n", __func__);
++ dev_err(dev, "%s: tee_shm_alloc_kernel_buf failed\n", __func__);
+ rc = -ENOMEM;
+ goto out_shm_alloc;
+ }
--- /dev/null
+From 231264d6927f6740af36855a622d0e240be9d94c Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Thu, 5 Aug 2021 09:27:16 -0400
+Subject: tracepoint: Fix static call function vs data state mismatch
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit 231264d6927f6740af36855a622d0e240be9d94c upstream.
+
+On a 1->0->1 callbacks transition, there is an issue with the new
+callback using the old callback's data.
+
+Considering __DO_TRACE_CALL:
+
+ do { \
+ struct tracepoint_func *it_func_ptr; \
+ void *__data; \
+ it_func_ptr = \
+ rcu_dereference_raw((&__tracepoint_##name)->funcs); \
+ if (it_func_ptr) { \
+ __data = (it_func_ptr)->data; \
+
+----> [ delayed here on one CPU (e.g. vcpu preempted by the host) ]
+
+ static_call(tp_func_##name)(__data, args); \
+ } \
+ } while (0)
+
+It has loaded the tp->funcs of the old callback, so it will try to use the old
+data. This can be fixed by adding a RCU sync anywhere in the 1->0->1
+transition chain.
+
+On a N->2->1 transition, we need an rcu-sync because you may have a
+sequence of 3->2->1 (or 1->2->1) where the element 0 data is unchanged
+between 2->1, but was changed from 3->2 (or from 1->2), which may be
+observed by the static call. This can be fixed by adding an
+unconditional RCU sync in transition 2->1.
+
+Note, this fixes a correctness issue at the cost of adding a tremendous
+performance regression to the disabling of tracepoints.
+
+Before this commit:
+
+ # trace-cmd start -e all
+ # time trace-cmd start -p nop
+
+ real 0m0.778s
+ user 0m0.000s
+ sys 0m0.061s
+
+After this commit:
+
+ # trace-cmd start -e all
+ # time trace-cmd start -p nop
+
+ real 0m10.593s
+ user 0m0.017s
+ sys 0m0.259s
+
+A follow up fix will introduce a more lightweight scheme based on RCU
+get_state and cond_sync, that will return the performance back to what it
+was. As both this change and the lightweight versions are complex on their
+own, for bisecting any issues that this may cause, they are kept as two
+separate changes.
+
+Link: https://lkml.kernel.org/r/20210805132717.23813-3-mathieu.desnoyers@efficios.com
+Link: https://lore.kernel.org/io-uring/4ebea8f0-58c9-e571-fd30-0ce4f6f09c70@samba.org/
+
+Cc: stable@vger.kernel.org
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: "Paul E. McKenney" <paulmck@kernel.org>
+Cc: Stefan Metzmacher <metze@samba.org>
+Fixes: d25e37d89dd2 ("tracepoint: Optimize using static_call()")
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/tracepoint.c | 102 +++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 82 insertions(+), 20 deletions(-)
+
+--- a/kernel/tracepoint.c
++++ b/kernel/tracepoint.c
+@@ -15,6 +15,13 @@
+ #include <linux/sched/task.h>
+ #include <linux/static_key.h>
+
++enum tp_func_state {
++ TP_FUNC_0,
++ TP_FUNC_1,
++ TP_FUNC_2,
++ TP_FUNC_N,
++};
++
+ extern tracepoint_ptr_t __start___tracepoints_ptrs[];
+ extern tracepoint_ptr_t __stop___tracepoints_ptrs[];
+
+@@ -267,26 +274,29 @@ static void *func_remove(struct tracepoi
+ return old;
+ }
+
+-static void tracepoint_update_call(struct tracepoint *tp, struct tracepoint_func *tp_funcs, bool sync)
++/*
++ * Count the number of functions (enum tp_func_state) in a tp_funcs array.
++ */
++static enum tp_func_state nr_func_state(const struct tracepoint_func *tp_funcs)
++{
++ if (!tp_funcs)
++ return TP_FUNC_0;
++ if (!tp_funcs[1].func)
++ return TP_FUNC_1;
++ if (!tp_funcs[2].func)
++ return TP_FUNC_2;
++ return TP_FUNC_N; /* 3 or more */
++}
++
++static void tracepoint_update_call(struct tracepoint *tp, struct tracepoint_func *tp_funcs)
+ {
+ void *func = tp->iterator;
+
+ /* Synthetic events do not have static call sites */
+ if (!tp->static_call_key)
+ return;
+-
+- if (!tp_funcs[1].func) {
++ if (nr_func_state(tp_funcs) == TP_FUNC_1)
+ func = tp_funcs[0].func;
+- /*
+- * If going from the iterator back to a single caller,
+- * we need to synchronize with __DO_TRACE to make sure
+- * that the data passed to the callback is the one that
+- * belongs to that callback.
+- */
+- if (sync)
+- tracepoint_synchronize_unregister();
+- }
+-
+ __static_call_update(tp->static_call_key, tp->static_call_tramp, func);
+ }
+
+@@ -320,9 +330,31 @@ static int tracepoint_add_func(struct tr
+ * a pointer to it. This array is referenced by __DO_TRACE from
+ * include/linux/tracepoint.h using rcu_dereference_sched().
+ */
+- tracepoint_update_call(tp, tp_funcs, false);
+- rcu_assign_pointer(tp->funcs, tp_funcs);
+- static_key_enable(&tp->key);
++ switch (nr_func_state(tp_funcs)) {
++ case TP_FUNC_1: /* 0->1 */
++ /* Set static call to first function */
++ tracepoint_update_call(tp, tp_funcs);
++ /* Both iterator and static call handle NULL tp->funcs */
++ rcu_assign_pointer(tp->funcs, tp_funcs);
++ static_key_enable(&tp->key);
++ break;
++ case TP_FUNC_2: /* 1->2 */
++ /* Set iterator static call */
++ tracepoint_update_call(tp, tp_funcs);
++ /*
++ * Iterator callback installed before updating tp->funcs.
++ * Requires ordering between RCU assign/dereference and
++ * static call update/call.
++ */
++ rcu_assign_pointer(tp->funcs, tp_funcs);
++ break;
++ case TP_FUNC_N: /* N->N+1 (N>1) */
++ rcu_assign_pointer(tp->funcs, tp_funcs);
++ break;
++ default:
++ WARN_ON_ONCE(1);
++ break;
++ }
+
+ release_probes(old);
+ return 0;
+@@ -349,17 +381,47 @@ static int tracepoint_remove_func(struct
+ /* Failed allocating new tp_funcs, replaced func with stub */
+ return 0;
+
+- if (!tp_funcs) {
++ switch (nr_func_state(tp_funcs)) {
++ case TP_FUNC_0: /* 1->0 */
+ /* Removed last function */
+ if (tp->unregfunc && static_key_enabled(&tp->key))
+ tp->unregfunc();
+
+ static_key_disable(&tp->key);
++ /* Set iterator static call */
++ tracepoint_update_call(tp, tp_funcs);
++ /* Both iterator and static call handle NULL tp->funcs */
++ rcu_assign_pointer(tp->funcs, NULL);
++ /*
++ * Make sure new func never uses old data after a 1->0->1
++ * transition sequence.
++ * Considering that transition 0->1 is the common case
++ * and don't have rcu-sync, issue rcu-sync after
++ * transition 1->0 to break that sequence by waiting for
++ * readers to be quiescent.
++ */
++ tracepoint_synchronize_unregister();
++ break;
++ case TP_FUNC_1: /* 2->1 */
+ rcu_assign_pointer(tp->funcs, tp_funcs);
+- } else {
++ /*
++ * On 2->1 transition, RCU sync is needed before setting
++ * static call to first callback, because the observer
++ * may have loaded any prior tp->funcs after the last one
++ * associated with an rcu-sync.
++ */
++ tracepoint_synchronize_unregister();
++ /* Set static call to first function */
++ tracepoint_update_call(tp, tp_funcs);
++ break;
++ case TP_FUNC_2: /* N->N-1 (N>2) */
++ fallthrough;
++ case TP_FUNC_N:
+ rcu_assign_pointer(tp->funcs, tp_funcs);
+- tracepoint_update_call(tp, tp_funcs,
+- tp_funcs[0].data != old[0].data);
++ break;
++ default:
++ WARN_ON_ONCE(1);
++ break;
+ }
+ release_probes(old);
+ return 0;
--- /dev/null
+From f7ec4121256393e1d03274acdca73eb18958f27e Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Thu, 5 Aug 2021 09:27:15 -0400
+Subject: tracepoint: static call: Compare data on transition from 2->1 callees
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit f7ec4121256393e1d03274acdca73eb18958f27e upstream.
+
+On transition from 2->1 callees, we should be comparing .data rather
+than .func, because the same callback can be registered twice with
+different data, and what we care about here is that the data of array
+element 0 is unchanged to skip rcu sync.
+
+Link: https://lkml.kernel.org/r/20210805132717.23813-2-mathieu.desnoyers@efficios.com
+Link: https://lore.kernel.org/io-uring/4ebea8f0-58c9-e571-fd30-0ce4f6f09c70@samba.org/
+
+Cc: stable@vger.kernel.org
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: "Paul E. McKenney" <paulmck@kernel.org>
+Cc: Stefan Metzmacher <metze@samba.org>
+Fixes: 547305a64632 ("tracepoint: Fix out of sync data passing by static caller")
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/tracepoint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/tracepoint.c
++++ b/kernel/tracepoint.c
+@@ -359,7 +359,7 @@ static int tracepoint_remove_func(struct
+ } else {
+ rcu_assign_pointer(tp->funcs, tp_funcs);
+ tracepoint_update_call(tp, tp_funcs,
+- tp_funcs[0].func != old[0].func);
++ tp_funcs[0].data != old[0].data);
+ }
+ release_probes(old);
+ return 0;
--- /dev/null
+From ff41c28c4b54052942180d8b3f49e75f1445135a Mon Sep 17 00:00:00 2001
+From: Kamal Agrawal <kamaagra@codeaurora.org>
+Date: Fri, 30 Jul 2021 18:53:06 +0530
+Subject: tracing: Fix NULL pointer dereference in start_creating
+
+From: Kamal Agrawal <kamaagra@codeaurora.org>
+
+commit ff41c28c4b54052942180d8b3f49e75f1445135a upstream.
+
+The event_trace_add_tracer() can fail. In this case, it leads to a crash
+in start_creating with below call stack. Handle the error scenario
+properly in trace_array_create_dir.
+
+Call trace:
+down_write+0x7c/0x204
+start_creating.25017+0x6c/0x194
+tracefs_create_file+0xc4/0x2b4
+init_tracer_tracefs+0x5c/0x940
+trace_array_create_dir+0x58/0xb4
+trace_array_create+0x1bc/0x2b8
+trace_array_get_by_name+0xdc/0x18c
+
+Link: https://lkml.kernel.org/r/1627651386-21315-1-git-send-email-kamaagra@codeaurora.org
+
+Cc: stable@vger.kernel.org
+Fixes: 4114fbfd02f1 ("tracing: Enable creating new instance early boot")
+Signed-off-by: Kamal Agrawal <kamaagra@codeaurora.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -8683,8 +8683,10 @@ static int trace_array_create_dir(struct
+ return -EINVAL;
+
+ ret = event_trace_add_tracer(tr->dir, tr);
+- if (ret)
++ if (ret) {
+ tracefs_remove(tr->dir);
++ return ret;
++ }
+
+ init_tracer_tracefs(tr, tr->dir);
+ __update_tracer_options(tr);
--- /dev/null
+From 2c05caa7ba8803209769b9e4fe02c38d77ae88d0 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Fri, 30 Jul 2021 17:19:51 -0400
+Subject: tracing / histogram: Give calculation hist_fields a size
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 2c05caa7ba8803209769b9e4fe02c38d77ae88d0 upstream.
+
+When working on my user space applications, I found a bug in the synthetic
+event code where the automated synthetic event field was not matching the
+event field calculation it was attached to. Looking deeper into it, it was
+because the calculation hist_field was not given a size.
+
+The synthetic event fields are matched to their hist_fields either by
+having the field have an identical string type, or if that does not match,
+then the size and signed values are used to match the fields.
+
+The problem arose when I tried to match a calculation where the fields
+were "unsigned int". My tool created a synthetic event of type "u32". But
+it failed to match. The string was:
+
+ diff=field1-field2:onmatch(event).trace(synth,$diff)
+
+Adding debugging into the kernel, I found that the size of "diff" was 0.
+And since it was given "unsigned int" as a type, the histogram fallback
+code used size and signed. The signed matched, but the size of u32 (4) did
+not match zero, and the event failed to be created.
+
+This can be worse if the field you want to match is not one of the
+acceptable fields for a synthetic event. As event fields can have any type
+that is supported in Linux, this can cause an issue. For example, if a
+type is an enum. Then there's no way to use that with any calculations.
+
+Have the calculation field simply take on the size of what it is
+calculating.
+
+Link: https://lkml.kernel.org/r/20210730171951.59c7743f@oasis.local.home
+
+Cc: Tom Zanussi <zanussi@kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: stable@vger.kernel.org
+Fixes: 100719dcef447 ("tracing: Add simple expression support to hist triggers")
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_events_hist.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -2271,6 +2271,10 @@ static struct hist_field *parse_expr(str
+
+ expr->operands[0] = operand1;
+ expr->operands[1] = operand2;
++
++ /* The operand sizes should be the same, so just pick one */
++ expr->size = operand1->size;
++
+ expr->operator = field_op;
+ expr->name = expr_str(expr, 0);
+ expr->type = kstrdup(operand1->type, GFP_KERNEL);
--- /dev/null
+From a9d10ca4986571bffc19778742d508cc8dd13e02 Mon Sep 17 00:00:00 2001
+From: Masami Hiramatsu <mhiramat@kernel.org>
+Date: Wed, 28 Jul 2021 07:55:43 +0900
+Subject: tracing: Reject string operand in the histogram expression
+
+From: Masami Hiramatsu <mhiramat@kernel.org>
+
+commit a9d10ca4986571bffc19778742d508cc8dd13e02 upstream.
+
+Since the string type can not be the target of the addition / subtraction
+operation, it must be rejected. Without this fix, the string type silently
+converted to digits.
+
+Link: https://lkml.kernel.org/r/162742654278.290973.1523000673366456634.stgit@devnote2
+
+Cc: stable@vger.kernel.org
+Fixes: 100719dcef447 ("tracing: Add simple expression support to hist triggers")
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_events_hist.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -65,7 +65,8 @@
+ C(INVALID_SORT_MODIFIER,"Invalid sort modifier"), \
+ C(EMPTY_SORT_FIELD, "Empty sort field"), \
+ C(TOO_MANY_SORT_FIELDS, "Too many sort fields (Max = 2)"), \
+- C(INVALID_SORT_FIELD, "Sort field must be a key or a val"),
++ C(INVALID_SORT_FIELD, "Sort field must be a key or a val"), \
++ C(INVALID_STR_OPERAND, "String type can not be an operand in expression"),
+
+ #undef C
+ #define C(a, b) HIST_ERR_##a
+@@ -2140,6 +2141,13 @@ static struct hist_field *parse_unary(st
+ ret = PTR_ERR(operand1);
+ goto free;
+ }
++ if (operand1->flags & HIST_FIELD_FL_STRING) {
++ /* String type can not be the operand of unary operator. */
++ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
++ destroy_hist_field(operand1, 0);
++ ret = -EINVAL;
++ goto free;
++ }
+
+ expr->flags |= operand1->flags &
+ (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
+@@ -2241,6 +2249,11 @@ static struct hist_field *parse_expr(str
+ operand1 = NULL;
+ goto free;
+ }
++ if (operand1->flags & HIST_FIELD_FL_STRING) {
++ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(operand1_str));
++ ret = -EINVAL;
++ goto free;
++ }
+
+ /* rest of string could be another expression e.g. b+c in a+b+c */
+ operand_flags = 0;
+@@ -2250,6 +2263,11 @@ static struct hist_field *parse_expr(str
+ operand2 = NULL;
+ goto free;
+ }
++ if (operand2->flags & HIST_FIELD_FL_STRING) {
++ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
++ ret = -EINVAL;
++ goto free;
++ }
+
+ ret = check_expr_operands(file->tr, operand1, operand2);
+ if (ret)