--- /dev/null
+From c550a59b06fe16e6154673f3d774efc6ef4d0411 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 09:50:20 +0100
+Subject: ARM: 9294/2: vfp: Fix broken softirq handling with instrumentation
+ enabled
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit c76c6c4ecbec0deb56a4f9e932b26866024a508f ]
+
+Commit 62b95a7b44d1 ("ARM: 9282/1: vfp: Manipulate task VFP state with
+softirqs disabled") replaced the en/disable preemption calls inside the
+VFP state handling code with en/disabling of soft IRQs, which is
+necessary to allow kernel use of the VFP/SIMD unit when handling a soft
+IRQ.
+
+Unfortunately, when lockdep is enabled (or other instrumentation that
+enables TRACE_IRQFLAGS), the disable path implemented in asm fails to
+perform the lockdep and RCU related bookkeeping, resulting in spurious
+warnings and other badness.
+
+Set let's rework the VFP entry code a little bit so we can make the
+local_bh_disable() call from C, with all the instrumentations that
+happen to have been configured. Calling local_bh_enable() can be done
+from asm, as it is a simple wrapper around __local_bh_enable_ip(), which
+is always a callable function.
+
+Link: https://lore.kernel.org/all/ZBBYCSZUJOWBg1s8@localhost.localdomain/
+
+Fixes: 62b95a7b44d1 ("ARM: 9282/1: vfp: Manipulate task VFP state with softirqs disabled")
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/include/asm/assembler.h | 13 -------------
+ arch/arm/vfp/entry.S | 11 +----------
+ arch/arm/vfp/vfphw.S | 12 ++++++------
+ arch/arm/vfp/vfpmodule.c | 27 ++++++++++++++++++++++-----
+ 4 files changed, 29 insertions(+), 34 deletions(-)
+
+diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
+index 06b48ce23e1ca..505a306e0271a 100644
+--- a/arch/arm/include/asm/assembler.h
++++ b/arch/arm/include/asm/assembler.h
+@@ -244,19 +244,6 @@ THUMB( fpreg .req r7 )
+ .endm
+ #endif
+
+- .macro local_bh_disable, ti, tmp
+- ldr \tmp, [\ti, #TI_PREEMPT]
+- add \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
+- str \tmp, [\ti, #TI_PREEMPT]
+- .endm
+-
+- .macro local_bh_enable_ti, ti, tmp
+- get_thread_info \ti
+- ldr \tmp, [\ti, #TI_PREEMPT]
+- sub \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET
+- str \tmp, [\ti, #TI_PREEMPT]
+- .endm
+-
+ #define USERL(l, x...) \
+ 9999: x; \
+ .pushsection __ex_table,"a"; \
+diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
+index 6dabb47617781..7483ef8bccda3 100644
+--- a/arch/arm/vfp/entry.S
++++ b/arch/arm/vfp/entry.S
+@@ -24,14 +24,5 @@
+ ENTRY(do_vfp)
+ mov r1, r10
+ mov r3, r9
+- ldr r4, .LCvfp
+- ldr pc, [r4] @ call VFP entry point
++ b vfp_entry
+ ENDPROC(do_vfp)
+-
+-ENTRY(vfp_null_entry)
+- ret lr
+-ENDPROC(vfp_null_entry)
+-
+- .align 2
+-.LCvfp:
+- .word vfp_vector
+diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
+index 60acd42e05786..4d8478264d82b 100644
+--- a/arch/arm/vfp/vfphw.S
++++ b/arch/arm/vfp/vfphw.S
+@@ -75,8 +75,6 @@
+ @ lr = unrecognised instruction return address
+ @ IRQs enabled.
+ ENTRY(vfp_support_entry)
+- local_bh_disable r1, r4
+-
+ ldr r11, [r1, #TI_CPU] @ CPU number
+ add r10, r1, #TI_VFPSTATE @ r10 = workspace
+
+@@ -179,9 +177,12 @@ vfp_hw_state_valid:
+ @ else it's one 32-bit instruction, so
+ @ always subtract 4 from the following
+ @ instruction address.
+- local_bh_enable_ti r10, r4
+- ret r3 @ we think we have handled things
+
++ mov lr, r3 @ we think we have handled things
++local_bh_enable_and_ret:
++ adr r0, .
++ mov r1, #SOFTIRQ_DISABLE_OFFSET
++ b __local_bh_enable_ip @ tail call
+
+ look_for_VFP_exceptions:
+ @ Check for synchronous or asynchronous exception
+@@ -204,8 +205,7 @@ skip:
+ @ not recognised by VFP
+
+ DBGSTR "not VFP"
+- local_bh_enable_ti r10, r4
+- ret lr
++ b local_bh_enable_and_ret
+
+ process_exception:
+ DBGSTR "bounce"
+diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
+index 01bc48d738478..349dcb944a937 100644
+--- a/arch/arm/vfp/vfpmodule.c
++++ b/arch/arm/vfp/vfpmodule.c
+@@ -32,10 +32,9 @@
+ /*
+ * Our undef handlers (in entry.S)
+ */
+-asmlinkage void vfp_support_entry(void);
+-asmlinkage void vfp_null_entry(void);
++asmlinkage void vfp_support_entry(u32, void *, u32, u32);
+
+-asmlinkage void (*vfp_vector)(void) = vfp_null_entry;
++static bool have_vfp __ro_after_init;
+
+ /*
+ * Dual-use variable.
+@@ -645,6 +644,25 @@ static int vfp_starting_cpu(unsigned int unused)
+ return 0;
+ }
+
++/*
++ * Entered with:
++ *
++ * r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
++ * r1 = thread_info pointer
++ * r2 = PC value to resume execution after successful emulation
++ * r3 = normal "successful" return address
++ * lr = unrecognised instruction return address
++ */
++asmlinkage void vfp_entry(u32 trigger, struct thread_info *ti, u32 resume_pc,
++ u32 resume_return_address)
++{
++ if (unlikely(!have_vfp))
++ return;
++
++ local_bh_disable();
++ vfp_support_entry(trigger, ti, resume_pc, resume_return_address);
++}
++
+ #ifdef CONFIG_KERNEL_MODE_NEON
+
+ static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr)
+@@ -798,7 +816,6 @@ static int __init vfp_init(void)
+ vfpsid = fmrx(FPSID);
+ barrier();
+ unregister_undef_hook(&vfp_detect_hook);
+- vfp_vector = vfp_null_entry;
+
+ pr_info("VFP support v0.3: ");
+ if (VFP_arch) {
+@@ -883,7 +900,7 @@ static int __init vfp_init(void)
+ "arm/vfp:starting", vfp_starting_cpu,
+ vfp_dying_cpu);
+
+- vfp_vector = vfp_support_entry;
++ have_vfp = true;
+
+ thread_register_notifier(&vfp_notifier_block);
+ vfp_pm_init();
+--
+2.39.2
+
--- /dev/null
+From bab5944176fce06f1af7be3e5fe15e0b0487e341 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 13:40:19 +0100
+Subject: ARM: 9297/1: vfp: avoid unbalanced stack on 'success' return path
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 2b951b0efbaa6c805854b60c11f08811054d50cd ]
+
+Commit c76c6c4ecbec0deb5 ("ARM: 9294/2: vfp: Fix broken softirq handling
+with instrumentation enabled") updated the VFP exception entry logic to
+go via a C function, so that we get the compiler's version of
+local_bh_disable(), which may be instrumented, and isn't generally
+callable from assembler.
+
+However, this assumes that passing an alternative 'success' return
+address works in C as it does in asm, and this is only the case if the C
+calls in question are tail calls, as otherwise, the stack will need some
+unwinding as well.
+
+I have already sent patches to the list that replace most of the asm
+logic with C code, and so it is preferable to have a minimal fix that
+addresses the issue and can be backported along with the commit that it
+
+fixes to v6.3 from v6.4. Hopefully, we can land the C conversion for v6.5.
+
+So instead of passing the 'success' return address as a function
+argument, pass the stack address from where to pop it so that both LR
+and SP have the expected value.
+
+Fixes: c76c6c4ecbec0deb5 ("ARM: 9294/2: vfp: Fix broken softirq handling with ...")
+Reported-by: syzbot+d4b00edc2d0c910d4bf4@syzkaller.appspotmail.com
+Tested-by: syzbot+d4b00edc2d0c910d4bf4@syzkaller.appspotmail.com
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Tested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Tested-by: Andre Przywara <andre.przywara@arm.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/vfp/entry.S | 7 +++++--
+ arch/arm/vfp/vfphw.S | 6 ++++--
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
+index 7483ef8bccda3..62206ef250371 100644
+--- a/arch/arm/vfp/entry.S
++++ b/arch/arm/vfp/entry.S
+@@ -23,6 +23,9 @@
+ @
+ ENTRY(do_vfp)
+ mov r1, r10
+- mov r3, r9
+- b vfp_entry
++ str lr, [sp, #-8]!
++ add r3, sp, #4
++ str r9, [r3]
++ bl vfp_entry
++ ldr pc, [sp], #8
+ ENDPROC(do_vfp)
+diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
+index 4d8478264d82b..a4610d0f32152 100644
+--- a/arch/arm/vfp/vfphw.S
++++ b/arch/arm/vfp/vfphw.S
+@@ -172,13 +172,14 @@ vfp_hw_state_valid:
+ @ out before setting an FPEXC that
+ @ stops us reading stuff
+ VFPFMXR FPEXC, r1 @ Restore FPEXC last
++ mov sp, r3 @ we think we have handled things
++ pop {lr}
+ sub r2, r2, #4 @ Retry current instruction - if Thumb
+ str r2, [sp, #S_PC] @ mode it's two 16-bit instructions,
+ @ else it's one 32-bit instruction, so
+ @ always subtract 4 from the following
+ @ instruction address.
+
+- mov lr, r3 @ we think we have handled things
+ local_bh_enable_and_ret:
+ adr r0, .
+ mov r1, #SOFTIRQ_DISABLE_OFFSET
+@@ -209,8 +210,9 @@ skip:
+
+ process_exception:
+ DBGSTR "bounce"
++ mov sp, r3 @ setup for a return to the user code.
++ pop {lr}
+ mov r2, sp @ nothing stacked - regdump is at TOS
+- mov lr, r3 @ setup for a return to the user code.
+
+ @ Now call the C code to package up the bounce to the support code
+ @ r0 holds the trigger instruction
+--
+2.39.2
+
--- /dev/null
+From c76cc53c0d9b35c08e372095009918fb409daf4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Apr 2023 10:14:29 -0600
+Subject: remoteproc: imx_dsp_rproc: Fix kernel test robot sparse warning
+
+From: Mathieu Poirier <mathieu.poirier@linaro.org>
+
+[ Upstream commit 3c497f624d40171ebead1a6705793100d92ecb85 ]
+
+This patch fixes the kernel test robot warning reported here:
+
+https://lore.kernel.org/bpf/642f916b.pPIKZ%2Fl%2F%2Fbw8tvIH%25lkp@intel.com/T/
+
+Fixes: 408ec1ff0caa ("remoteproc: imx_dsp_rproc: Add custom memory copy implementation for i.MX DSP Cores")
+Link: https://lore.kernel.org/r/20230407161429.3973177-1-mathieu.poirier@linaro.org
+Tested-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/imx_dsp_rproc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
+index e8e23f6b85563..dcd07a6a5e945 100644
+--- a/drivers/remoteproc/imx_dsp_rproc.c
++++ b/drivers/remoteproc/imx_dsp_rproc.c
+@@ -727,12 +727,12 @@ static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
+ * The IRAM is part of the HiFi DSP.
+ * According to hw specs only 32-bits writes are allowed.
+ */
+-static int imx_dsp_rproc_memcpy(void *dest, const void *src, size_t size)
++static int imx_dsp_rproc_memcpy(void *dst, const void *src, size_t size)
+ {
++ void __iomem *dest = (void __iomem *)dst;
+ const u8 *src_byte = src;
+ const u32 *source = src;
+ u32 affected_mask;
+- u32 *dst = dest;
+ int i, q, r;
+ u32 tmp;
+
+@@ -745,7 +745,7 @@ static int imx_dsp_rproc_memcpy(void *dest, const void *src, size_t size)
+
+ /* copy data in units of 32 bits at a time */
+ for (i = 0; i < q; i++)
+- writel(source[i], &dst[i]);
++ writel(source[i], dest + i * 4);
+
+ if (r) {
+ affected_mask = GENMASK(8 * r, 0);
+@@ -776,8 +776,8 @@ static int imx_dsp_rproc_memcpy(void *dest, const void *src, size_t size)
+ */
+ static int imx_dsp_rproc_memset(void *addr, u8 value, size_t size)
+ {
++ void __iomem *tmp_dst = (void __iomem *)addr;
+ u32 tmp_val = value;
+- u32 *tmp_dst = addr;
+ u32 affected_mask;
+ int q, r;
+ u32 tmp;
+--
+2.39.2
+