--- /dev/null
+From 70550d9a74bbdba512f073c52544ddb38caa9bb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 17:11:59 +0800
+Subject: 9p/fd: Use P9_HDRSZ for header size
+
+From: GUO Zihua <guozihua@huawei.com>
+
+[ Upstream commit 6854fadbeee10891ed74246bdc05031906b6c8cf ]
+
+Cleanup hardcoded header sizes to use P9_HDRSZ instead of '7'
+
+Link: https://lkml.kernel.org/r/20221117091159.31533-4-guozihua@huawei.com
+Signed-off-by: GUO Zihua <guozihua@huawei.com>
+Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com>
+[Dominique: commit message adjusted to make sense after offset size
+adjustment got removed]
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_fd.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index e1c2c9242ce2..f359cfdc1858 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -122,7 +122,7 @@ struct p9_conn {
+ struct list_head unsent_req_list;
+ struct p9_req_t *rreq;
+ struct p9_req_t *wreq;
+- char tmp_buf[7];
++ char tmp_buf[P9_HDRSZ];
+ struct p9_fcall rc;
+ int wpos;
+ int wsize;
+@@ -295,7 +295,7 @@ static void p9_read_work(struct work_struct *work)
+ if (!m->rc.sdata) {
+ m->rc.sdata = m->tmp_buf;
+ m->rc.offset = 0;
+- m->rc.capacity = 7; /* start by reading header */
++ m->rc.capacity = P9_HDRSZ; /* start by reading header */
+ }
+
+ clear_bit(Rpending, &m->wsched);
+@@ -318,7 +318,7 @@ static void p9_read_work(struct work_struct *work)
+ p9_debug(P9_DEBUG_TRANS, "got new header\n");
+
+ /* Header size */
+- m->rc.size = 7;
++ m->rc.size = P9_HDRSZ;
+ err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0);
+ if (err) {
+ p9_debug(P9_DEBUG_ERROR,
+--
+2.35.1
+
--- /dev/null
+From 85e653d9ea170535ce5097b48ff5c315e9319cfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 22:44:41 +0900
+Subject: 9p/xen: check logical size for buffer size
+
+From: Dominique Martinet <asmadeus@codewreck.org>
+
+[ Upstream commit 391c18cf776eb4569ecda1f7794f360fe0a45a26 ]
+
+trans_xen did not check the data fits into the buffer before copying
+from the xen ring, but we probably should.
+Add a check that just skips the request and return an error to
+userspace if it did not fit
+
+Tested-by: Stefano Stabellini <sstabellini@kernel.org>
+Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com>
+Link: https://lkml.kernel.org/r/20221118135542.63400-1-asmadeus@codewreck.org
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_xen.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 427f6caefa29..4255f2a3bea4 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -231,6 +231,14 @@ static void p9_xen_response(struct work_struct *work)
+ continue;
+ }
+
++ if (h.size > req->rc.capacity) {
++ dev_warn(&priv->dev->dev,
++ "requested packet size too big: %d for tag %d with capacity %zd\n",
++ h.size, h.tag, req->rc.capacity);
++ req->status = REQ_STATUS_ERROR;
++ goto recv_error;
++ }
++
+ memcpy(&req->rc, &h, sizeof(h));
+ req->rc.offset = 0;
+
+@@ -240,6 +248,7 @@ static void p9_xen_response(struct work_struct *work)
+ masked_prod, &masked_cons,
+ XEN_9PFS_RING_SIZE(ring));
+
++recv_error:
+ virt_mb();
+ cons += h.size;
+ ring->intf->in_cons = cons;
+--
+2.35.1
+
--- /dev/null
+From 3fcf08ba607bc087be505b4dce6b293bd0a85a01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 15:23:50 -0800
+Subject: ALSA: seq: Fix function prototype mismatch in
+ snd_seq_expand_var_event
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 05530ef7cf7c7d700f6753f058999b1b5099a026 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed.
+
+seq_copy_in_user() and seq_copy_in_kernel() did not have prototypes
+matching snd_seq_dump_func_t. Adjust this and remove the casts. There
+are not resulting binary output differences.
+
+This was found as a result of Clang's new -Wcast-function-type-strict
+flag, which is more sensitive than the simpler -Wcast-function-type,
+which only checks for type width mismatches.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/lkml/202211041527.HD8TLSE1-lkp@intel.com
+Cc: Jaroslav Kysela <perex@perex.cz>
+Cc: Takashi Iwai <tiwai@suse.com>
+Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
+Cc: alsa-devel@alsa-project.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20221118232346.never.380-kees@kernel.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/seq/seq_memory.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
+index b7aee23fc387..47ef6bc30c0e 100644
+--- a/sound/core/seq/seq_memory.c
++++ b/sound/core/seq/seq_memory.c
+@@ -113,15 +113,19 @@ EXPORT_SYMBOL(snd_seq_dump_var_event);
+ * expand the variable length event to linear buffer space.
+ */
+
+-static int seq_copy_in_kernel(char **bufptr, const void *src, int size)
++static int seq_copy_in_kernel(void *ptr, void *src, int size)
+ {
++ char **bufptr = ptr;
++
+ memcpy(*bufptr, src, size);
+ *bufptr += size;
+ return 0;
+ }
+
+-static int seq_copy_in_user(char __user **bufptr, const void *src, int size)
++static int seq_copy_in_user(void *ptr, void *src, int size)
+ {
++ char __user **bufptr = ptr;
++
+ if (copy_to_user(*bufptr, src, size))
+ return -EFAULT;
+ *bufptr += size;
+@@ -151,8 +155,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
+ return newlen;
+ }
+ err = snd_seq_dump_var_event(event,
+- in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel :
+- (snd_seq_dump_func_t)seq_copy_in_user,
++ in_kernel ? seq_copy_in_kernel : seq_copy_in_user,
+ &buf);
+ return err < 0 ? err : newlen;
+ }
+--
+2.35.1
+
--- /dev/null
+From 2c4f3d521c29ea7600be7fab85d9af3880470d91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Sep 2022 16:09:12 +0100
+Subject: ARM: 9251/1: perf: Fix stacktraces for tracepoint events in THUMB2
+ kernels
+
+From: Tomislav Novak <tnovak@fb.com>
+
+[ Upstream commit 612695bccfdbd52004551308a55bae410e7cd22f ]
+
+Store the frame address where arm_get_current_stackframe() looks for it
+(ARM_r7 instead of ARM_fp if CONFIG_THUMB2_KERNEL=y). Otherwise frame->fp
+gets set to 0, causing unwind_frame() to fail.
+
+ # bpftrace -e 't:sched:sched_switch { @[kstack] = count(); exit(); }'
+ Attaching 1 probe...
+ @[
+ __schedule+1059
+ ]: 1
+
+A typical first unwind instruction is 0x97 (SP = R7), so after executing
+it SP ends up being 0 and -URC_FAILURE is returned.
+
+ unwind_frame(pc = ac9da7d7 lr = 00000000 sp = c69bdda0 fp = 00000000)
+ unwind_find_idx(ac9da7d7)
+ unwind_exec_insn: insn = 00000097
+ unwind_exec_insn: fp = 00000000 sp = 00000000 lr = 00000000 pc = 00000000
+
+With this patch:
+
+ # bpftrace -e 't:sched:sched_switch { @[kstack] = count(); exit(); }'
+ Attaching 1 probe...
+ @[
+ __schedule+1059
+ __schedule+1059
+ schedule+79
+ schedule_hrtimeout_range_clock+163
+ schedule_hrtimeout_range+17
+ ep_poll+471
+ SyS_epoll_wait+111
+ sys_epoll_pwait+231
+ __ret_fast_syscall+1
+ ]: 1
+
+Link: https://lore.kernel.org/r/20220920230728.2617421-1-tnovak@fb.com/
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Tomislav Novak <tnovak@fb.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/include/asm/perf_event.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
+index fe87397c3d8c..bdbc1e590891 100644
+--- a/arch/arm/include/asm/perf_event.h
++++ b/arch/arm/include/asm/perf_event.h
+@@ -17,7 +17,7 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs);
+
+ #define perf_arch_fetch_caller_regs(regs, __ip) { \
+ (regs)->ARM_pc = (__ip); \
+- (regs)->ARM_fp = (unsigned long) __builtin_frame_address(0); \
++ frame_pointer((regs)) = (unsigned long) __builtin_frame_address(0); \
+ (regs)->ARM_sp = current_stack_pointer; \
+ (regs)->ARM_cpsr = SVC_MODE; \
+ }
+--
+2.35.1
+
--- /dev/null
+From 2897ebb8ac059d102217959d448a9d0cdf33bcbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 21:46:18 +0100
+Subject: ARM: 9266/1: mm: fix no-MMU ZERO_PAGE() implementation
+
+From: Giulio Benetti <giulio.benetti@benettiengineering.com>
+
+[ Upstream commit 340a982825f76f1cff0daa605970fe47321b5ee7 ]
+
+Actually in no-MMU SoCs(i.e. i.MXRT) ZERO_PAGE(vaddr) expands to
+```
+virt_to_page(0)
+```
+that in order expands to:
+```
+pfn_to_page(virt_to_pfn(0))
+```
+and then virt_to_pfn(0) to:
+```
+ ((((unsigned long)(0) - PAGE_OFFSET) >> PAGE_SHIFT) +
+ PHYS_PFN_OFFSET)
+```
+where PAGE_OFFSET and PHYS_PFN_OFFSET are the DRAM offset(0x80000000) and
+PAGE_SHIFT is 12. This way we obtain 16MB(0x01000000) summed to the base of
+DRAM(0x80000000).
+When ZERO_PAGE(0) is then used, for example in bio_add_page(), the page
+gets an address that is out of DRAM bounds.
+So instead of using fake virtual page 0 let's allocate a dedicated
+zero_page during paging_init() and assign it to a global 'struct page *
+empty_zero_page' the same way mmu.c does and it's the same approach used
+in m68k with commit dc068f462179 as discussed here[0]. Then let's move
+ZERO_PAGE() definition to the top of pgtable.h to be in common between
+mmu.c and nommu.c.
+
+[0]: https://lore.kernel.org/linux-m68k/2a462b23-5b8e-bbf4-ec7d-778434a3b9d7@google.com/T/#m1266ceb63
+ad140743174d6b3070364d3c9a5179b
+
+Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/include/asm/pgtable-nommu.h | 6 ------
+ arch/arm/include/asm/pgtable.h | 16 +++++++++-------
+ arch/arm/mm/nommu.c | 19 +++++++++++++++++++
+ 3 files changed, 28 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
+index d16aba48fa0a..090011394477 100644
+--- a/arch/arm/include/asm/pgtable-nommu.h
++++ b/arch/arm/include/asm/pgtable-nommu.h
+@@ -44,12 +44,6 @@
+
+ typedef pte_t *pte_addr_t;
+
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-#define ZERO_PAGE(vaddr) (virt_to_page(0))
+-
+ /*
+ * Mark the prot value as uncacheable and unbufferable.
+ */
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index cd1f84bb40ae..a25c4303fc0e 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -10,6 +10,15 @@
+ #include <linux/const.h>
+ #include <asm/proc-fns.h>
+
++#ifndef __ASSEMBLY__
++/*
++ * ZERO_PAGE is a global shared page that is always zero: used
++ * for zero-mapped memory areas etc..
++ */
++extern struct page *empty_zero_page;
++#define ZERO_PAGE(vaddr) (empty_zero_page)
++#endif
++
+ #ifndef CONFIG_MMU
+
+ #include <asm-generic/pgtable-nopud.h>
+@@ -156,13 +165,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ #define __S111 __PAGE_SHARED_EXEC
+
+ #ifndef __ASSEMBLY__
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-extern struct page *empty_zero_page;
+-#define ZERO_PAGE(vaddr) (empty_zero_page)
+-
+
+ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
+index 2658f52903da..88feffebae21 100644
+--- a/arch/arm/mm/nommu.c
++++ b/arch/arm/mm/nommu.c
+@@ -26,6 +26,13 @@
+
+ unsigned long vectors_base;
+
++/*
++ * empty_zero_page is a special page that is used for
++ * zero-initialized data and COW.
++ */
++struct page *empty_zero_page;
++EXPORT_SYMBOL(empty_zero_page);
++
+ #ifdef CONFIG_ARM_MPU
+ struct mpu_rgn_info mpu_rgn_info;
+ #endif
+@@ -148,9 +155,21 @@ void __init adjust_lowmem_bounds(void)
+ */
+ void __init paging_init(const struct machine_desc *mdesc)
+ {
++ void *zero_page;
++
+ early_trap_init((void *)vectors_base);
+ mpu_setup();
++
++ /* allocate the zero page. */
++ zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
++ if (!zero_page)
++ panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
++ __func__, PAGE_SIZE, PAGE_SIZE);
++
+ bootmem_init();
++
++ empty_zero_page = virt_to_page(zero_page);
++ flush_dcache_page(empty_zero_page);
+ }
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 397f3352f6a91c775548c33da88fd03ea1bd3549 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Oct 2022 21:56:29 +0100
+Subject: ARM: dts: rockchip: disable arm_global_timer on rk3066 and rk3188
+
+From: Johan Jonker <jbx6244@gmail.com>
+
+[ Upstream commit da74858a475782a3f16470907814c8cc5950ad68 ]
+
+The clock source and the sched_clock provided by the arm_global_timer
+on Rockchip rk3066a/rk3188 are quite unstable because their rates
+depend on the CPU frequency.
+
+Recent changes to the arm_global_timer driver makes it impossible to use.
+
+On the other side, the arm_global_timer has a higher rating than the
+ROCKCHIP_TIMER, it will be selected by default by the time framework
+while we want to use the stable Rockchip clock source.
+
+Keep the arm_global_timer disabled in order to have the
+DW_APB_TIMER (rk3066a) or ROCKCHIP_TIMER (rk3188) selected by default.
+
+Signed-off-by: Johan Jonker <jbx6244@gmail.com>
+Link: https://lore.kernel.org/r/f275ca8d-fd0a-26e5-b978-b7f3df815e0a@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/rk3188.dtsi | 1 -
+ arch/arm/boot/dts/rk3xxx.dtsi | 7 +++++++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
+index 7c8c5c28dc2e..e07b1d79c470 100644
+--- a/arch/arm/boot/dts/rk3188.dtsi
++++ b/arch/arm/boot/dts/rk3188.dtsi
+@@ -606,7 +606,6 @@
+
+ &global_timer {
+ interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+- status = "disabled";
+ };
+
+ &local_timer {
+diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
+index 616a828e0c6e..17e89d30de78 100644
+--- a/arch/arm/boot/dts/rk3xxx.dtsi
++++ b/arch/arm/boot/dts/rk3xxx.dtsi
+@@ -76,6 +76,13 @@
+ reg = <0x1013c200 0x20>;
+ interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
+ clocks = <&cru CORE_PERI>;
++ status = "disabled";
++ /* The clock source and the sched_clock provided by the arm_global_timer
++ * on Rockchip rk3066a/rk3188 are quite unstable because their rates
++ * depend on the CPU frequency.
++ * Keep the arm_global_timer disabled in order to have the
++ * DW_APB_TIMER (rk3066a) or ROCKCHIP_TIMER (rk3188) selected by default.
++ */
+ };
+
+ local_timer: local-timer@1013c600 {
+--
+2.35.1
+
--- /dev/null
+From 07b94c4a81f747f6198f6fc354b3e2bce2cbe92c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 10:58:22 +0200
+Subject: ARM: dts: rockchip: fix ir-receiver node names
+
+From: Johan Jonker <jbx6244@gmail.com>
+
+[ Upstream commit dd847fe34cdf1e89afed1af24986359f13082bfb ]
+
+Fix ir-receiver node names on Rockchip boards,
+so that they match with regex: '^ir(-receiver)?(@[a-f0-9]+)?$'
+
+Signed-off-by: Johan Jonker <jbx6244@gmail.com>
+Link: https://lore.kernel.org/r/ea5af279-f44c-afea-023d-bb37f5a0d58d@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/rk3188-radxarock.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
+index 36c0945f43b2..3718fac62841 100644
+--- a/arch/arm/boot/dts/rk3188-radxarock.dts
++++ b/arch/arm/boot/dts/rk3188-radxarock.dts
+@@ -71,7 +71,7 @@
+ #sound-dai-cells = <0>;
+ };
+
+- ir_recv: gpio-ir-receiver {
++ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+--
+2.35.1
+
--- /dev/null
+From 73d67a6f20f5639b351779a21f4a35dff511b911 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 18:55:46 +0200
+Subject: arm: dts: rockchip: fix node name for hym8563 rtc
+
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+
+[ Upstream commit 17b57beafccb4569accbfc8c11390744cf59c021 ]
+
+Fix the node name for hym8563 in all arm rockchip devicetrees.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20221024165549.74574-4-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/rk3036-evb.dts | 2 +-
+ arch/arm/boot/dts/rk3288-evb-act8846.dts | 2 +-
+ arch/arm/boot/dts/rk3288-firefly.dtsi | 2 +-
+ arch/arm/boot/dts/rk3288-miqi.dts | 2 +-
+ arch/arm/boot/dts/rk3288-rock2-square.dts | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts
+index 2a7e6624efb9..ea23ba98625e 100644
+--- a/arch/arm/boot/dts/rk3036-evb.dts
++++ b/arch/arm/boot/dts/rk3036-evb.dts
+@@ -31,7 +31,7 @@
+ &i2c1 {
+ status = "okay";
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts
+index be695b8c1f67..8a635c243127 100644
+--- a/arch/arm/boot/dts/rk3288-evb-act8846.dts
++++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts
+@@ -54,7 +54,7 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563@51 {
++ rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+
+diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
+index 7fb582302b32..c560afe3af78 100644
+--- a/arch/arm/boot/dts/rk3288-firefly.dtsi
++++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
+@@ -233,7 +233,7 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts
+index 713f55e143c6..e3d5644f2915 100644
+--- a/arch/arm/boot/dts/rk3288-miqi.dts
++++ b/arch/arm/boot/dts/rk3288-miqi.dts
+@@ -162,7 +162,7 @@
+ vin-supply = <&vcc_sys>;
+ };
+
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts
+index c4d1d142d8c6..d5ef99ebbddc 100644
+--- a/arch/arm/boot/dts/rk3288-rock2-square.dts
++++ b/arch/arm/boot/dts/rk3288-rock2-square.dts
+@@ -165,7 +165,7 @@
+ };
+
+ &i2c0 {
+- hym8563: hym8563@51 {
++ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+--
+2.35.1
+
--- /dev/null
+From 2908771a21e41d3607f3bb366b05582ff94dac7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 18:55:47 +0200
+Subject: arm: dts: rockchip: remove clock-frequency from rtc
+
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+
+[ Upstream commit 6122f3be70d90a1b2a1188d8910256fc218376a9 ]
+
+'clock-frequency' is not part of the DT binding and not supported by the
+Linux driver.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20221024165549.74574-5-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/rk3036-evb.dts | 1 -
+ arch/arm/boot/dts/rk3288-firefly.dtsi | 1 -
+ arch/arm/boot/dts/rk3288-miqi.dts | 1 -
+ arch/arm/boot/dts/rk3288-rock2-square.dts | 1 -
+ arch/arm/boot/dts/rk3288-vmarc-som.dtsi | 1 -
+ 5 files changed, 5 deletions(-)
+
+diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts
+index ea23ba98625e..94216f870b57 100644
+--- a/arch/arm/boot/dts/rk3036-evb.dts
++++ b/arch/arm/boot/dts/rk3036-evb.dts
+@@ -35,7 +35,6 @@
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+ };
+diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
+index c560afe3af78..74ba7e21850a 100644
+--- a/arch/arm/boot/dts/rk3288-firefly.dtsi
++++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
+@@ -237,7 +237,6 @@
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio7>;
+ interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts
+index e3d5644f2915..db1eb648e0e1 100644
+--- a/arch/arm/boot/dts/rk3288-miqi.dts
++++ b/arch/arm/boot/dts/rk3288-miqi.dts
+@@ -166,7 +166,6 @@
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+
+diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts
+index d5ef99ebbddc..bc44606ca05d 100644
+--- a/arch/arm/boot/dts/rk3288-rock2-square.dts
++++ b/arch/arm/boot/dts/rk3288-rock2-square.dts
+@@ -169,7 +169,6 @@
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+diff --git a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
+index 0ae2bd150e37..793951655b73 100644
+--- a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
++++ b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
+@@ -241,7 +241,6 @@
+ interrupt-parent = <&gpio5>;
+ interrupts = <RK_PC3 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+--
+2.35.1
+
--- /dev/null
+From 1c16a5e1bdd757fdedcfb491b6ca80c5be9d00a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 01:31:37 +0200
+Subject: ARM: dts: rockchip: rk3188: fix lcdc1-rgb24 node name
+
+From: Johan Jonker <jbx6244@gmail.com>
+
+[ Upstream commit 11871e20bcb23c00966e785a124fb72bc8340af4 ]
+
+The lcdc1-rgb24 node name is out of line with the rest
+of the rk3188 lcdc1 node, so fix it.
+
+Signed-off-by: Johan Jonker <jbx6244@gmail.com>
+Link: https://lore.kernel.org/r/7b9c0a6f-626b-07e8-ae74-7e0f08b8d241@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/rk3188.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
+index 2c606494b78c..7c8c5c28dc2e 100644
+--- a/arch/arm/boot/dts/rk3188.dtsi
++++ b/arch/arm/boot/dts/rk3188.dtsi
+@@ -378,7 +378,7 @@
+ rockchip,pins = <2 RK_PD3 1 &pcfg_pull_none>;
+ };
+
+- lcdc1_rgb24: ldcd1-rgb24 {
++ lcdc1_rgb24: lcdc1-rgb24 {
+ rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>,
+ <2 RK_PA1 1 &pcfg_pull_none>,
+ <2 RK_PA2 1 &pcfg_pull_none>,
+--
+2.35.1
+
--- /dev/null
+From c8bfe969b42eaf39bc84aff74ebc6ee8397edb9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 10:59:10 +0200
+Subject: arm64: dts: rockchip: fix ir-receiver node names
+
+From: Johan Jonker <jbx6244@gmail.com>
+
+[ Upstream commit de0d04b9780a23eb928aedfb6f981285f78d58e5 ]
+
+Fix ir-receiver node names on Rockchip boards,
+so that they match with regex: '^ir(-receiver)?(@[a-f0-9]+)?$'
+
+Signed-off-by: Johan Jonker <jbx6244@gmail.com>
+Link: https://lore.kernel.org/r/e9764253-8ce8-150b-4820-41f03f845469@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+index ea6820902ede..7ea48167747c 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+@@ -19,7 +19,7 @@
+ stdout-path = "serial2:1500000n8";
+ };
+
+- ir_rx {
++ ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+--
+2.35.1
+
--- /dev/null
+From 7904b837b69290a0f4ee1f95887e2eddfe4b4662 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Sep 2022 11:28:12 +0000
+Subject: arm64: dts: rockchip: keep I2S1 disabled for GPIO function on ROCK Pi
+ 4 series
+
+From: FUKAUMI Naoki <naoki@radxa.com>
+
+[ Upstream commit 849c19d14940b87332d5d59c7fc581d73f2099fd ]
+
+I2S1 pins are exposed on 40-pin header on Radxa ROCK Pi 4 series.
+their default function is GPIO, so I2S1 need to be disabled.
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20220924112812.1219-1-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+index 100a769165ef..a7ec81657503 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+@@ -446,7 +446,6 @@
+ &i2s1 {
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+- status = "okay";
+ };
+
+ &i2s2 {
+--
+2.35.1
+
--- /dev/null
+From 1a4f163765e6e2d3032bfa845132060178a7472e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 17:03:18 +0800
+Subject: ASoC: rt711-sdca: fix the latency time of clock stop prepare state
+ machine transitions
+
+From: Shuming Fan <shumingf@realtek.com>
+
+[ Upstream commit c7d7d4e7bb1290cc473610b0bb96d9fa606d00e7 ]
+
+Due to the hardware behavior, it takes some time for CBJ detection/impedance sensing/de-bounce.
+The ClockStop_NotFinished flag will be raised until these functions are completed.
+In ClockStopMode0 mode case, the SdW controller might check this flag from D3 to D0 when the
+jack detection interrupt happened.
+
+Signed-off-by: Shuming Fan <shumingf@realtek.com>
+Link: https://lore.kernel.org/r/20221116090318.5017-1-shumingf@realtek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt711-sdca-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c
+index a085b2f530aa..31e77d462ef3 100644
+--- a/sound/soc/codecs/rt711-sdca-sdw.c
++++ b/sound/soc/codecs/rt711-sdca-sdw.c
+@@ -230,7 +230,7 @@ static int rt711_sdca_read_prop(struct sdw_slave *slave)
+ }
+
+ /* set the timeout values */
+- prop->clk_stop_timeout = 20;
++ prop->clk_stop_timeout = 700;
+
+ /* wake-up event */
+ prop->wake_capable = 1;
+--
+2.35.1
+
--- /dev/null
+From 37878788979781bf9560feb52252ac5b3dad384d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 12:01:13 +0530
+Subject: ASoC: soc-pcm: Add NULL check in BE reparenting
+
+From: Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
+
+[ Upstream commit db8f91d424fe0ea6db337aca8bc05908bbce1498 ]
+
+Add NULL check in dpcm_be_reparent API, to handle
+kernel NULL pointer dereference error.
+The issue occurred in fuzzing test.
+
+Signed-off-by: Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
+Link: https://lore.kernel.org/r/1669098673-29703-1-git-send-email-quic_srivasam@quicinc.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-pcm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index f6dc71e8ea87..3b673477f621 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -1166,6 +1166,8 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
+ return;
+
+ be_substream = snd_soc_dpcm_get_substream(be, stream);
++ if (!be_substream)
++ return;
+
+ for_each_dpcm_fe(be, stream, dpcm) {
+ if (dpcm->fe == fe)
+--
+2.35.1
+
--- /dev/null
+From 848dd5be1215db1ab0714c57c1d77b8dc5a65520 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 20:13:54 +0800
+Subject: ASoC: wm8962: Wait for updated value of WM8962_CLOCKING1 register
+
+From: Chancel Liu <chancel.liu@nxp.com>
+
+[ Upstream commit 3ca507bf99611c82dafced73e921c1b10ee12869 ]
+
+DSPCLK_DIV field in WM8962_CLOCKING1 register is used to generate
+correct frequency of LRCLK and BCLK. Sometimes the read-only value
+can't be updated timely after enabling SYSCLK. This results in wrong
+calculation values. Delay is introduced here to wait for newest value
+from register. The time of the delay should be at least 500~1000us
+according to test.
+
+Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20221109121354.123958-1-chancel.liu@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wm8962.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
+index 09a73b854964..779f7097d336 100644
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -2490,6 +2490,14 @@ static void wm8962_configure_bclk(struct snd_soc_component *component)
+ snd_soc_component_update_bits(component, WM8962_CLOCKING2,
+ WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);
+
++ /* DSPCLK_DIV field in WM8962_CLOCKING1 register is used to generate
++ * correct frequency of LRCLK and BCLK. Sometimes the read-only value
++ * can't be updated timely after enabling SYSCLK. This results in wrong
++ * calculation values. Delay is introduced here to wait for newest
++ * value from register. The time of the delay should be at least
++ * 500~1000us according to test.
++ */
++ usleep_range(500, 1000);
+ dspclk = snd_soc_component_read(component, WM8962_CLOCKING1);
+
+ if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
+--
+2.35.1
+
--- /dev/null
+From 5d242611e674c83a16db5fe6b7087ab7d3698f49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 16:29:44 +0000
+Subject: btrfs: send: avoid unaligned encoded writes when attempting to clone
+ range
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit a11452a3709e217492798cf3686ac2cc8eb3fb51 ]
+
+When trying to see if we can clone a file range, there are cases where we
+end up sending two write operations in case the inode from the source root
+has an i_size that is not sector size aligned and the length from the
+current offset to its i_size is less than the remaining length we are
+trying to clone.
+
+Issuing two write operations when we could instead issue a single write
+operation is not incorrect. However it is not optimal, specially if the
+extents are compressed and the flag BTRFS_SEND_FLAG_COMPRESSED was passed
+to the send ioctl. In that case we can end up sending an encoded write
+with an offset that is not sector size aligned, which makes the receiver
+fallback to decompressing the data and writing it using regular buffered
+IO (so re-compressing the data in case the fs is mounted with compression
+enabled), because encoded writes fail with -EINVAL when an offset is not
+sector size aligned.
+
+The following example, which triggered a bug in the receiver code for the
+fallback logic of decompressing + regular buffer IO and is fixed by the
+patchset referred in a Link at the bottom of this changelog, is an example
+where we have the non-optimal behaviour due to an unaligned encoded write:
+
+ $ cat test.sh
+ #!/bin/bash
+
+ DEV=/dev/sdj
+ MNT=/mnt/sdj
+
+ mkfs.btrfs -f $DEV > /dev/null
+ mount -o compress $DEV $MNT
+
+ # File foo has a size of 33K, not aligned to the sector size.
+ xfs_io -f -c "pwrite -S 0xab 0 33K" $MNT/foo
+
+ xfs_io -f -c "pwrite -S 0xcd 0 64K" $MNT/bar
+
+ # Now clone the first 32K of file bar into foo at offset 0.
+ xfs_io -c "reflink $MNT/bar 0 0 32K" $MNT/foo
+
+ # Snapshot the default subvolume and create a full send stream (v2).
+ btrfs subvolume snapshot -r $MNT $MNT/snap
+
+ btrfs send --compressed-data -f /tmp/test.send $MNT/snap
+
+ echo -e "\nFile bar in the original filesystem:"
+ od -A d -t x1 $MNT/snap/bar
+
+ umount $MNT
+ mkfs.btrfs -f $DEV > /dev/null
+ mount $DEV $MNT
+
+ echo -e "\nReceiving stream in a new filesystem..."
+ btrfs receive -f /tmp/test.send $MNT
+
+ echo -e "\nFile bar in the new filesystem:"
+ od -A d -t x1 $MNT/snap/bar
+
+ umount $MNT
+
+Before this patch, the send stream included one regular write and one
+encoded write for file 'bar', with the later being not sector size aligned
+and causing the receiver to fallback to decompression + buffered writes.
+The output of the btrfs receive command in verbose mode (-vvv):
+
+ (...)
+ mkfile o258-7-0
+ rename o258-7-0 -> bar
+ utimes
+ clone bar - source=foo source offset=0 offset=0 length=32768
+ write bar - offset=32768 length=1024
+ encoded_write bar - offset=33792, len=4096, unencoded_offset=33792, unencoded_file_len=31744, unencoded_len=65536, compression=1, encryption=0
+ encoded_write bar - falling back to decompress and write due to errno 22 ("Invalid argument")
+ (...)
+
+This patch avoids the regular write followed by an unaligned encoded write
+so that we end up sending a single encoded write that is aligned. So after
+this patch the stream content is (output of btrfs receive -vvv):
+
+ (...)
+ mkfile o258-7-0
+ rename o258-7-0 -> bar
+ utimes
+ clone bar - source=foo source offset=0 offset=0 length=32768
+ encoded_write bar - offset=32768, len=4096, unencoded_offset=32768, unencoded_file_len=32768, unencoded_len=65536, compression=1, encryption=0
+ (...)
+
+So we get more optimal behaviour and avoid the silent data loss bug in
+versions of btrfs-progs affected by the bug referred by the Link tag
+below (btrfs-progs v5.19, v5.19.1, v6.0 and v6.0.1).
+
+Link: https://lore.kernel.org/linux-btrfs/cover.1668529099.git.fdmanana@suse.com/
+Reviewed-by: Boris Burkov <boris@bur.io>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/send.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index 4d2c6ce29fe5..9250a17731bd 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5398,6 +5398,7 @@ static int clone_range(struct send_ctx *sctx,
+ u64 ext_len;
+ u64 clone_len;
+ u64 clone_data_offset;
++ bool crossed_src_i_size = false;
+
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(clone_root->root, path);
+@@ -5454,8 +5455,10 @@ static int clone_range(struct send_ctx *sctx,
+ if (key.offset >= clone_src_i_size)
+ break;
+
+- if (key.offset + ext_len > clone_src_i_size)
++ if (key.offset + ext_len > clone_src_i_size) {
+ ext_len = clone_src_i_size - key.offset;
++ crossed_src_i_size = true;
++ }
+
+ clone_data_offset = btrfs_file_extent_offset(leaf, ei);
+ if (btrfs_file_extent_disk_bytenr(leaf, ei) == disk_byte) {
+@@ -5515,6 +5518,25 @@ static int clone_range(struct send_ctx *sctx,
+ ret = send_clone(sctx, offset, clone_len,
+ clone_root);
+ }
++ } else if (crossed_src_i_size && clone_len < len) {
++ /*
++ * If we are at i_size of the clone source inode and we
++ * can not clone from it, terminate the loop. This is
++ * to avoid sending two write operations, one with a
++ * length matching clone_len and the final one after
++ * this loop with a length of len - clone_len.
++ *
++ * When using encoded writes (BTRFS_SEND_FLAG_COMPRESSED
++ * was passed to the send ioctl), this helps avoid
++ * sending an encoded write for an offset that is not
++ * sector size aligned, in case the i_size of the source
++ * inode is not sector size aligned. That will make the
++ * receiver fallback to decompression of the data and
++ * writing it using regular buffered IO, therefore while
++ * not incorrect, it's not optimal due decompression and
++ * possible re-compression at the receiver.
++ */
++ break;
+ } else {
+ ret = send_extent_data(sctx, offset, clone_len);
+ }
+--
+2.35.1
+
--- /dev/null
+From 8f63844347774a20f7425409db5e4fa5463a8f27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 20:45:28 +0800
+Subject: cifs: fix use-after-free caused by invalid pointer `hostname`
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit 153695d36ead0ccc4d0256953c751cabf673e621 ]
+
+`hostname` needs to be set as null-pointer after free in
+`cifs_put_tcp_session` function, or when `cifsd` thread attempts
+to resolve hostname and reconnect the host, the thread would deref
+the invalid pointer.
+
+Here is one of practical backtrace examples as reference:
+
+Task 477
+---------------------------
+ do_mount
+ path_mount
+ do_new_mount
+ vfs_get_tree
+ smb3_get_tree
+ smb3_get_tree_common
+ cifs_smb3_do_mount
+ cifs_mount
+ mount_put_conns
+ cifs_put_tcp_session
+ --> kfree(server->hostname)
+
+cifsd
+---------------------------
+ kthread
+ cifs_demultiplex_thread
+ cifs_reconnect
+ reconn_set_ipaddr_from_hostname
+ --> if (!server->hostname)
+ --> if (server->hostname[0] == '\0') // !! UAF fault here
+
+CIFS: VFS: cifs_mount failed w/return code = -112
+mount error(112): Host is down
+BUG: KASAN: use-after-free in reconn_set_ipaddr_from_hostname+0x2ba/0x310
+Read of size 1 at addr ffff888108f35380 by task cifsd/480
+CPU: 2 PID: 480 Comm: cifsd Not tainted 6.1.0-rc2-00106-gf705792f89dd-dirty #25
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x68/0x85
+ print_report+0x16c/0x4a3
+ kasan_report+0x95/0x190
+ reconn_set_ipaddr_from_hostname+0x2ba/0x310
+ __cifs_reconnect.part.0+0x241/0x800
+ cifs_reconnect+0x65f/0xb60
+ cifs_demultiplex_thread+0x1570/0x2570
+ kthread+0x2c5/0x380
+ ret_from_fork+0x22/0x30
+ </TASK>
+Allocated by task 477:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ __kasan_kmalloc+0x7e/0x90
+ __kmalloc_node_track_caller+0x52/0x1b0
+ kstrdup+0x3b/0x70
+ cifs_get_tcp_session+0xbc/0x19b0
+ mount_get_conns+0xa9/0x10c0
+ cifs_mount+0xdf/0x1970
+ cifs_smb3_do_mount+0x295/0x1660
+ smb3_get_tree+0x352/0x5e0
+ vfs_get_tree+0x8e/0x2e0
+ path_mount+0xf8c/0x1990
+ do_mount+0xee/0x110
+ __x64_sys_mount+0x14b/0x1f0
+ do_syscall_64+0x3b/0x90
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+Freed by task 477:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ kasan_save_free_info+0x2a/0x50
+ __kasan_slab_free+0x10a/0x190
+ __kmem_cache_free+0xca/0x3f0
+ cifs_put_tcp_session+0x30c/0x450
+ cifs_mount+0xf95/0x1970
+ cifs_smb3_do_mount+0x295/0x1660
+ smb3_get_tree+0x352/0x5e0
+ vfs_get_tree+0x8e/0x2e0
+ path_mount+0xf8c/0x1990
+ do_mount+0xee/0x110
+ __x64_sys_mount+0x14b/0x1f0
+ do_syscall_64+0x3b/0x90
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+The buggy address belongs to the object at ffff888108f35380
+ which belongs to the cache kmalloc-16 of size 16
+The buggy address is located 0 bytes inside of
+ 16-byte region [ffff888108f35380, ffff888108f35390)
+The buggy address belongs to the physical page:
+page:00000000333f8e58 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff888108f350e0 pfn:0x108f35
+flags: 0x200000000000200(slab|node=0|zone=2)
+raw: 0200000000000200 0000000000000000 dead000000000122 ffff8881000423c0
+raw: ffff888108f350e0 000000008080007a 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+Memory state around the buggy address:
+ ffff888108f35280: fa fb fc fc fa fb fc fc fa fb fc fc fa fb fc fc
+ ffff888108f35300: fa fb fc fc fa fb fc fc fa fb fc fc fa fb fc fc
+>ffff888108f35380: fa fb fc fc fa fb fc fc fa fb fc fc fa fb fc fc
+ ^
+ ffff888108f35400: fa fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff888108f35480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+
+Fixes: 7be3248f3139 ("cifs: To match file servers, make sure the server hostname matches")
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/connect.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index c6e2a0ff8f0c..a4284c4d7e03 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1392,6 +1392,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
+ server->session_key.response = NULL;
+ server->session_key.len = 0;
+ kfree(server->hostname);
++ server->hostname = NULL;
+
+ task = xchg(&server->tsk, NULL);
+ if (task)
+--
+2.35.1
+
--- /dev/null
+From 735e7af7970c9c9a34a41c67fd3dd7ba8d6c7c8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 09:57:35 +0200
+Subject: clk: generalize devm_clk_get() a bit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit abae8e57e49aa75f6db76aa866c775721523908f ]
+
+Allow to add an exit hook to devm managed clocks. Also use
+clk_get_optional() in devm_clk_get_optional instead of open coding it.
+The generalisation will be used in the next commit to add some more
+devm_clk helpers.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <aardelean@deviqon.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20220520075737.758761-3-u.kleine-koenig@pengutronix.de
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: c61bfb1cb63d ("mmc: mtk-sd: Fix missing clk_disable_unprepare in msdc_of_clock_parse()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-devres.c | 66 +++++++++++++++++++++++++++++-----------
+ 1 file changed, 49 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
+index f9d5b7334341..c822f4ef1584 100644
+--- a/drivers/clk/clk-devres.c
++++ b/drivers/clk/clk-devres.c
+@@ -4,39 +4,71 @@
+ #include <linux/export.h>
+ #include <linux/gfp.h>
+
++struct devm_clk_state {
++ struct clk *clk;
++ void (*exit)(struct clk *clk);
++};
++
+ static void devm_clk_release(struct device *dev, void *res)
+ {
+- clk_put(*(struct clk **)res);
++ struct devm_clk_state *state = *(struct devm_clk_state **)res;
++
++ if (state->exit)
++ state->exit(state->clk);
++
++ clk_put(state->clk);
+ }
+
+-struct clk *devm_clk_get(struct device *dev, const char *id)
++static struct clk *__devm_clk_get(struct device *dev, const char *id,
++ struct clk *(*get)(struct device *dev, const char *id),
++ int (*init)(struct clk *clk),
++ void (*exit)(struct clk *clk))
+ {
+- struct clk **ptr, *clk;
++ struct devm_clk_state *state;
++ struct clk *clk;
++ int ret;
+
+- ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+- if (!ptr)
++ state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
++ if (!state)
+ return ERR_PTR(-ENOMEM);
+
+- clk = clk_get(dev, id);
+- if (!IS_ERR(clk)) {
+- *ptr = clk;
+- devres_add(dev, ptr);
+- } else {
+- devres_free(ptr);
++ clk = get(dev, id);
++ if (IS_ERR(clk)) {
++ ret = PTR_ERR(clk);
++ goto err_clk_get;
+ }
+
++ if (init) {
++ ret = init(clk);
++ if (ret)
++ goto err_clk_init;
++ }
++
++ state->clk = clk;
++ state->exit = exit;
++
++ devres_add(dev, state);
++
+ return clk;
++
++err_clk_init:
++
++ clk_put(clk);
++err_clk_get:
++
++ devres_free(state);
++ return ERR_PTR(ret);
++}
++
++struct clk *devm_clk_get(struct device *dev, const char *id)
++{
++ return __devm_clk_get(dev, id, clk_get, NULL, NULL);
+ }
+ EXPORT_SYMBOL(devm_clk_get);
+
+ struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+ {
+- struct clk *clk = devm_clk_get(dev, id);
+-
+- if (clk == ERR_PTR(-ENOENT))
+- return NULL;
+-
+- return clk;
++ return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
+ }
+ EXPORT_SYMBOL(devm_clk_get_optional);
+
+--
+2.35.1
+
--- /dev/null
+From dbaaea6aa026d010688d1e6430b4571279b6b784 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 09:57:36 +0200
+Subject: clk: Provide new devm_clk helpers for prepared and enabled clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 7ef9651e9792b08eb310c6beb202cbc947f43cab ]
+
+When a driver keeps a clock prepared (or enabled) during the whole
+lifetime of the driver, these helpers allow to simplify the drivers.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Alexandru Ardelean <aardelean@deviqon.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20220520075737.758761-4-u.kleine-koenig@pengutronix.de
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: c61bfb1cb63d ("mmc: mtk-sd: Fix missing clk_disable_unprepare in msdc_of_clock_parse()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-devres.c | 27 ++++++++++
+ include/linux/clk.h | 109 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 136 insertions(+)
+
+diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
+index c822f4ef1584..43ccd20e0298 100644
+--- a/drivers/clk/clk-devres.c
++++ b/drivers/clk/clk-devres.c
+@@ -66,12 +66,39 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
+ }
+ EXPORT_SYMBOL(devm_clk_get);
+
++struct clk *devm_clk_get_prepared(struct device *dev, const char *id)
++{
++ return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare);
++}
++EXPORT_SYMBOL_GPL(devm_clk_get_prepared);
++
++struct clk *devm_clk_get_enabled(struct device *dev, const char *id)
++{
++ return __devm_clk_get(dev, id, clk_get,
++ clk_prepare_enable, clk_disable_unprepare);
++}
++EXPORT_SYMBOL_GPL(devm_clk_get_enabled);
++
+ struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+ {
+ return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
+ }
+ EXPORT_SYMBOL(devm_clk_get_optional);
+
++struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id)
++{
++ return __devm_clk_get(dev, id, clk_get_optional,
++ clk_prepare, clk_unprepare);
++}
++EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared);
++
++struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
++{
++ return __devm_clk_get(dev, id, clk_get_optional,
++ clk_prepare_enable, clk_disable_unprepare);
++}
++EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
++
+ struct clk_bulk_devres {
+ struct clk_bulk_data *clks;
+ int num_clks;
+diff --git a/include/linux/clk.h b/include/linux/clk.h
+index 266e8de3cb51..e280e0acb55c 100644
+--- a/include/linux/clk.h
++++ b/include/linux/clk.h
+@@ -458,6 +458,47 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
+ */
+ struct clk *devm_clk_get(struct device *dev, const char *id);
+
++/**
++ * devm_clk_get_prepared - devm_clk_get() + clk_prepare()
++ * @dev: device for clock "consumer"
++ * @id: clock consumer ID
++ *
++ * Context: May sleep.
++ *
++ * Return: a struct clk corresponding to the clock producer, or
++ * valid IS_ERR() condition containing errno. The implementation
++ * uses @dev and @id to determine the clock consumer, and thereby
++ * the clock producer. (IOW, @id may be identical strings, but
++ * clk_get may return different clock producers depending on @dev.)
++ *
++ * The returned clk (if valid) is prepared. Drivers must however assume
++ * that the clock is not enabled.
++ *
++ * The clock will automatically be unprepared and freed when the device
++ * is unbound from the bus.
++ */
++struct clk *devm_clk_get_prepared(struct device *dev, const char *id);
++
++/**
++ * devm_clk_get_enabled - devm_clk_get() + clk_prepare_enable()
++ * @dev: device for clock "consumer"
++ * @id: clock consumer ID
++ *
++ * Context: May sleep.
++ *
++ * Return: a struct clk corresponding to the clock producer, or
++ * valid IS_ERR() condition containing errno. The implementation
++ * uses @dev and @id to determine the clock consumer, and thereby
++ * the clock producer. (IOW, @id may be identical strings, but
++ * clk_get may return different clock producers depending on @dev.)
++ *
++ * The returned clk (if valid) is prepared and enabled.
++ *
++ * The clock will automatically be disabled, unprepared and freed
++ * when the device is unbound from the bus.
++ */
++struct clk *devm_clk_get_enabled(struct device *dev, const char *id);
++
+ /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ * clock producer.
+@@ -469,6 +510,50 @@ struct clk *devm_clk_get(struct device *dev, const char *id);
+ */
+ struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
++/**
++ * devm_clk_get_optional_prepared - devm_clk_get_optional() + clk_prepare()
++ * @dev: device for clock "consumer"
++ * @id: clock consumer ID
++ *
++ * Context: May sleep.
++ *
++ * Return: a struct clk corresponding to the clock producer, or
++ * valid IS_ERR() condition containing errno. The implementation
++ * uses @dev and @id to determine the clock consumer, and thereby
++ * the clock producer. If no such clk is found, it returns NULL
++ * which serves as a dummy clk. That's the only difference compared
++ * to devm_clk_get_prepared().
++ *
++ * The returned clk (if valid) is prepared. Drivers must however
++ * assume that the clock is not enabled.
++ *
++ * The clock will automatically be unprepared and freed when the
++ * device is unbound from the bus.
++ */
++struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id);
++
++/**
++ * devm_clk_get_optional_enabled - devm_clk_get_optional() +
++ * clk_prepare_enable()
++ * @dev: device for clock "consumer"
++ * @id: clock consumer ID
++ *
++ * Context: May sleep.
++ *
++ * Return: a struct clk corresponding to the clock producer, or
++ * valid IS_ERR() condition containing errno. The implementation
++ * uses @dev and @id to determine the clock consumer, and thereby
++ * the clock producer. If no such clk is found, it returns NULL
++ * which serves as a dummy clk. That's the only difference compared
++ * to devm_clk_get_enabled().
++ *
++ * The returned clk (if valid) is prepared and enabled.
++ *
++ * The clock will automatically be disabled, unprepared and freed
++ * when the device is unbound from the bus.
++ */
++struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id);
++
+ /**
+ * devm_get_clk_from_child - lookup and obtain a managed reference to a
+ * clock producer from child node.
+@@ -813,12 +898,36 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id)
+ return NULL;
+ }
+
++static inline struct clk *devm_clk_get_prepared(struct device *dev,
++ const char *id)
++{
++ return NULL;
++}
++
++static inline struct clk *devm_clk_get_enabled(struct device *dev,
++ const char *id)
++{
++ return NULL;
++}
++
+ static inline struct clk *devm_clk_get_optional(struct device *dev,
+ const char *id)
+ {
+ return NULL;
+ }
+
++static inline struct clk *devm_clk_get_optional_prepared(struct device *dev,
++ const char *id)
++{
++ return NULL;
++}
++
++static inline struct clk *devm_clk_get_optional_enabled(struct device *dev,
++ const char *id)
++{
++ return NULL;
++}
++
+ static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
+ struct clk_bulk_data *clks)
+ {
+--
+2.35.1
+
--- /dev/null
+From 979641a42a9a7bea7789b52ddb9d28ff62ddc791 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Nov 2021 03:30:02 +0800
+Subject: drm/bridge: anx7625: Fix edid_read break case in sp_tx_edid_read()
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit 0bae5687bc689b64343fd8b52db2ad9e448f3f16 ]
+
+edid_read() was assumed to return 0 on success. After commit
+7f16d0f3b8e2("drm/bridge: anx7625: Propagate errors from sp_tx_rst_aux()"),
+the function will return > 0 for successful case, representing the i2c
+read bytes. Otherwise -EIO on failure cases. Update the g_edid_break
+break condition accordingly.
+
+Fixes: 7f16d0f3b8e2("drm/bridge: anx7625: Propagate errors from sp_tx_rst_aux()")
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Reviewed-by: Xin Ji <xji@analogixsemi.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211118193002.407168-1-hsinyi@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/anx7625.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index 392a9c56e9a0..f895ef1939fa 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -796,7 +796,7 @@ static int sp_tx_edid_read(struct anx7625_data *ctx,
+ int count, blocks_num;
+ u8 pblock_buf[MAX_DPCD_BUFFER_SIZE];
+ u8 i, j;
+- u8 g_edid_break = 0;
++ int g_edid_break = 0;
+ int ret;
+ struct device *dev = &ctx->client->dev;
+
+@@ -827,7 +827,7 @@ static int sp_tx_edid_read(struct anx7625_data *ctx,
+ g_edid_break = edid_read(ctx, offset,
+ pblock_buf);
+
+- if (g_edid_break)
++ if (g_edid_break < 0)
+ break;
+
+ memcpy(&pedid_blocks_buf[offset],
+--
+2.35.1
+
--- /dev/null
+From 8bfcef83422886e108c91a908f62bcc88826c244 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 00:27:58 +0900
+Subject: fbcon: Use kzalloc() in fbcon_prepare_logo()
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit a6a00d7e8ffd78d1cdb7a43f1278f081038c638f ]
+
+A kernel built with syzbot's config file reported that
+
+ scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2))
+
+causes uninitialized "save" to be copied.
+
+ ----------
+ [drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
+ [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
+ Console: switching to colour frame buffer device 128x48
+ =====================================================
+ BUG: KMSAN: uninit-value in do_update_region+0x4b8/0xba0
+ do_update_region+0x4b8/0xba0
+ update_region+0x40d/0x840
+ fbcon_switch+0x3364/0x35e0
+ redraw_screen+0xae3/0x18a0
+ do_bind_con_driver+0x1cb3/0x1df0
+ do_take_over_console+0x11cb/0x13f0
+ fbcon_fb_registered+0xacc/0xfd0
+ register_framebuffer+0x1179/0x1320
+ __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
+ drm_fbdev_client_hotplug+0xbea/0xda0
+ drm_fbdev_generic_setup+0x65e/0x9d0
+ vkms_init+0x9f3/0xc76
+ (...snipped...)
+
+ Uninit was stored to memory at:
+ fbcon_prepare_logo+0x143b/0x1940
+ fbcon_init+0x2c1b/0x31c0
+ visual_init+0x3e7/0x820
+ do_bind_con_driver+0x14a4/0x1df0
+ do_take_over_console+0x11cb/0x13f0
+ fbcon_fb_registered+0xacc/0xfd0
+ register_framebuffer+0x1179/0x1320
+ __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
+ drm_fbdev_client_hotplug+0xbea/0xda0
+ drm_fbdev_generic_setup+0x65e/0x9d0
+ vkms_init+0x9f3/0xc76
+ (...snipped...)
+
+ Uninit was created at:
+ __kmem_cache_alloc_node+0xb69/0x1020
+ __kmalloc+0x379/0x680
+ fbcon_prepare_logo+0x704/0x1940
+ fbcon_init+0x2c1b/0x31c0
+ visual_init+0x3e7/0x820
+ do_bind_con_driver+0x14a4/0x1df0
+ do_take_over_console+0x11cb/0x13f0
+ fbcon_fb_registered+0xacc/0xfd0
+ register_framebuffer+0x1179/0x1320
+ __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
+ drm_fbdev_client_hotplug+0xbea/0xda0
+ drm_fbdev_generic_setup+0x65e/0x9d0
+ vkms_init+0x9f3/0xc76
+ (...snipped...)
+
+ CPU: 2 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc4-00356-g8f2975c2bb4c #924
+ Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+ ----------
+
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/cad03d25-0ea0-32c4-8173-fd1895314bce@I-love.SAKURA.ne.jp
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/core/fbcon.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index e035a63bbe5b..1f37904b0405 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -601,7 +601,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
+ if (scr_readw(r) != vc->vc_video_erase_char)
+ break;
+ if (r != q && new_rows >= rows + logo_lines) {
+- save = kmalloc(array3_size(logo_lines, new_cols, 2),
++ save = kzalloc(array3_size(logo_lines, new_cols, 2),
+ GFP_KERNEL);
+ if (save) {
+ int i = cols < new_cols ? cols : new_cols;
+--
+2.35.1
+
--- /dev/null
+From 27d93ddd76f49197ea33a02ef566240f82fc2455 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 18:52:56 +0100
+Subject: fs: use acquire ordering in __fget_light()
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 7ee47dcfff1835ff75a794d1075b6b5f5462cfed ]
+
+We must prevent the CPU from reordering the files->count read with the
+FD table access like this, on architectures where read-read reordering is
+possible:
+
+ files_lookup_fd_raw()
+ close_fd()
+ put_files_struct()
+ atomic_read(&files->count)
+
+I would like to mark this for stable, but the stable rules explicitly say
+"no theoretical races", and given that the FD table pointer and
+files->count are explicitly stored in the same cacheline, this sort of
+reordering seems quite unlikely in practice...
+
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/file.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/fs/file.c b/fs/file.c
+index ee9317346702..214364e19d76 100644
+--- a/fs/file.c
++++ b/fs/file.c
+@@ -1029,7 +1029,16 @@ static unsigned long __fget_light(unsigned int fd, fmode_t mask)
+ struct files_struct *files = current->files;
+ struct file *file;
+
+- if (atomic_read(&files->count) == 1) {
++ /*
++ * If another thread is concurrently calling close_fd() followed
++ * by put_files_struct(), we must not observe the old table
++ * entry combined with the new refcount - otherwise we could
++ * return a file that is concurrently being freed.
++ *
++ * atomic_read_acquire() pairs with atomic_dec_and_test() in
++ * put_files_struct().
++ */
++ if (atomic_read_acquire(&files->count) == 1) {
+ file = files_lookup_fd_raw(files, fd);
+ if (!file || unlikely(file->f_mode & mask))
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From dbda5c7a363fd0fc18d8678410dbb945fabe1382 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 13:04:34 +0000
+Subject: media: videobuf2-core: take mmap_lock in vb2_get_unmapped_area()
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 098e5edc5d048a8df8691fd9fde895af100be42b ]
+
+While vb2_mmap took the mmap_lock mutex, vb2_get_unmapped_area didn't.
+Add this.
+
+Also take this opportunity to move the 'q->memory != VB2_MEMORY_MMAP'
+check and vb2_fileio_is_active() check into __find_plane_by_offset() so
+both vb2_mmap and vb2_get_unmapped_area do the same checks.
+
+Since q->memory is checked while mmap_lock is held, also take that lock
+in reqbufs and create_bufs when it is set, and set it back to
+MEMORY_UNKNOWN on error.
+
+Fixes: f035eb4e976e ("[media] videobuf2: fix lockdep warning")
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Acked-by: Tomasz Figa <tfiga@chromium.org>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/common/videobuf2/videobuf2-core.c | 102 +++++++++++++-----
+ 1 file changed, 73 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
+index 033b0c83272f..30c8497f7c11 100644
+--- a/drivers/media/common/videobuf2/videobuf2-core.c
++++ b/drivers/media/common/videobuf2/videobuf2-core.c
+@@ -788,7 +788,13 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
+ num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME);
+ memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
++ /*
++ * Set this now to ensure that drivers see the correct q->memory value
++ * in the queue_setup op.
++ */
++ mutex_lock(&q->mmap_lock);
+ q->memory = memory;
++ mutex_unlock(&q->mmap_lock);
+
+ /*
+ * Ask the driver how many buffers and planes per buffer it requires.
+@@ -797,22 +803,27 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
+ plane_sizes, q->alloc_devs);
+ if (ret)
+- return ret;
++ goto error;
+
+ /* Check that driver has set sane values */
+- if (WARN_ON(!num_planes))
+- return -EINVAL;
++ if (WARN_ON(!num_planes)) {
++ ret = -EINVAL;
++ goto error;
++ }
+
+ for (i = 0; i < num_planes; i++)
+- if (WARN_ON(!plane_sizes[i]))
+- return -EINVAL;
++ if (WARN_ON(!plane_sizes[i])) {
++ ret = -EINVAL;
++ goto error;
++ }
+
+ /* Finally, allocate buffers and video memory */
+ allocated_buffers =
+ __vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);
+ if (allocated_buffers == 0) {
+ dprintk(q, 1, "memory allocation failed\n");
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto error;
+ }
+
+ /*
+@@ -853,7 +864,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ if (ret < 0) {
+ /*
+ * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+- * from q->num_buffers.
++ * from q->num_buffers and it will reset q->memory to
++ * VB2_MEMORY_UNKNOWN.
+ */
+ __vb2_queue_free(q, allocated_buffers);
+ mutex_unlock(&q->mmap_lock);
+@@ -869,6 +881,12 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ q->waiting_for_buffers = !q->is_output;
+
+ return 0;
++
++error:
++ mutex_lock(&q->mmap_lock);
++ q->memory = VB2_MEMORY_UNKNOWN;
++ mutex_unlock(&q->mmap_lock);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_core_reqbufs);
+
+@@ -879,6 +897,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ {
+ unsigned int num_planes = 0, num_buffers, allocated_buffers;
+ unsigned plane_sizes[VB2_MAX_PLANES] = { };
++ bool no_previous_buffers = !q->num_buffers;
+ int ret;
+
+ if (q->num_buffers == VB2_MAX_FRAME) {
+@@ -886,13 +905,19 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ return -ENOBUFS;
+ }
+
+- if (!q->num_buffers) {
++ if (no_previous_buffers) {
+ if (q->waiting_in_dqbuf && *count) {
+ dprintk(q, 1, "another dup()ped fd is waiting for a buffer\n");
+ return -EBUSY;
+ }
+ memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
++ /*
++ * Set this now to ensure that drivers see the correct q->memory
++ * value in the queue_setup op.
++ */
++ mutex_lock(&q->mmap_lock);
+ q->memory = memory;
++ mutex_unlock(&q->mmap_lock);
+ q->waiting_for_buffers = !q->is_output;
+ } else {
+ if (q->memory != memory) {
+@@ -915,14 +940,15 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ ret = call_qop(q, queue_setup, q, &num_buffers,
+ &num_planes, plane_sizes, q->alloc_devs);
+ if (ret)
+- return ret;
++ goto error;
+
+ /* Finally, allocate buffers and video memory */
+ allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers,
+ num_planes, plane_sizes);
+ if (allocated_buffers == 0) {
+ dprintk(q, 1, "memory allocation failed\n");
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto error;
+ }
+
+ /*
+@@ -953,7 +979,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ if (ret < 0) {
+ /*
+ * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+- * from q->num_buffers.
++ * from q->num_buffers and it will reset q->memory to
++ * VB2_MEMORY_UNKNOWN.
+ */
+ __vb2_queue_free(q, allocated_buffers);
+ mutex_unlock(&q->mmap_lock);
+@@ -968,6 +995,14 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ *count = allocated_buffers;
+
+ return 0;
++
++error:
++ if (no_previous_buffers) {
++ mutex_lock(&q->mmap_lock);
++ q->memory = VB2_MEMORY_UNKNOWN;
++ mutex_unlock(&q->mmap_lock);
++ }
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_core_create_bufs);
+
+@@ -2124,6 +2159,22 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
+ struct vb2_buffer *vb;
+ unsigned int buffer, plane;
+
++ /*
++ * Sanity checks to ensure the lock is held, MEMORY_MMAP is
++ * used and fileio isn't active.
++ */
++ lockdep_assert_held(&q->mmap_lock);
++
++ if (q->memory != VB2_MEMORY_MMAP) {
++ dprintk(q, 1, "queue is not currently set up for mmap\n");
++ return -EINVAL;
++ }
++
++ if (vb2_fileio_is_active(q)) {
++ dprintk(q, 1, "file io in progress\n");
++ return -EBUSY;
++ }
++
+ /*
+ * Go over all buffers and their planes, comparing the given offset
+ * with an offset assigned to each plane. If a match is found,
+@@ -2225,11 +2276,6 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
+ int ret;
+ unsigned long length;
+
+- if (q->memory != VB2_MEMORY_MMAP) {
+- dprintk(q, 1, "queue is not currently set up for mmap\n");
+- return -EINVAL;
+- }
+-
+ /*
+ * Check memory area access mode.
+ */
+@@ -2251,14 +2297,9 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
+
+ mutex_lock(&q->mmap_lock);
+
+- if (vb2_fileio_is_active(q)) {
+- dprintk(q, 1, "mmap: file io in progress\n");
+- ret = -EBUSY;
+- goto unlock;
+- }
+-
+ /*
+- * Find the plane corresponding to the offset passed by userspace.
++ * Find the plane corresponding to the offset passed by userspace. This
++ * will return an error if not MEMORY_MMAP or file I/O is in progress.
+ */
+ ret = __find_plane_by_offset(q, off, &buffer, &plane);
+ if (ret)
+@@ -2311,22 +2352,25 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
+ void *vaddr;
+ int ret;
+
+- if (q->memory != VB2_MEMORY_MMAP) {
+- dprintk(q, 1, "queue is not currently set up for mmap\n");
+- return -EINVAL;
+- }
++ mutex_lock(&q->mmap_lock);
+
+ /*
+- * Find the plane corresponding to the offset passed by userspace.
++ * Find the plane corresponding to the offset passed by userspace. This
++ * will return an error if not MEMORY_MMAP or file I/O is in progress.
+ */
+ ret = __find_plane_by_offset(q, off, &buffer, &plane);
+ if (ret)
+- return ret;
++ goto unlock;
+
+ vb = q->bufs[buffer];
+
+ vaddr = vb2_plane_vaddr(vb, plane);
++ mutex_unlock(&q->mmap_lock);
+ return vaddr ? (unsigned long)vaddr : -EINVAL;
++
++unlock:
++ mutex_unlock(&q->mmap_lock);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
+ #endif
+--
+2.35.1
+
--- /dev/null
+From 7123be4ec55bea7acc8de2b8aee3ca8ecab2f4a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 18:16:04 +0100
+Subject: mm/khugepaged: fix GUP-fast interaction by sending IPI
+
+From: Jann Horn <jannh@google.com>
+
+commit 2ba99c5e08812494bc57f319fb562f527d9bacd8 upstream.
+
+Since commit 70cbc3cc78a99 ("mm: gup: fix the fast GUP race against THP
+collapse"), the lockless_pages_from_mm() fastpath rechecks the pmd_t to
+ensure that the page table was not removed by khugepaged in between.
+
+However, lockless_pages_from_mm() still requires that the page table is
+not concurrently freed. Fix it by sending IPIs (if the architecture uses
+semi-RCU-style page table freeing) before freeing/reusing page tables.
+
+Link: https://lkml.kernel.org/r/20221129154730.2274278-2-jannh@google.com
+Link: https://lkml.kernel.org/r/20221128180252.1684965-2-jannh@google.com
+Link: https://lkml.kernel.org/r/20221125213714.4115729-2-jannh@google.com
+Fixes: ba76149f47d8 ("thp: khugepaged")
+Signed-off-by: Jann Horn <jannh@google.com>
+Reviewed-by: Yang Shi <shy828301@gmail.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[manual backport: two of the three places in khugepaged that can free
+ptes were refactored into a common helper between 5.15 and 6.0]
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/asm-generic/tlb.h | 4 ++++
+ mm/khugepaged.c | 3 +++
+ mm/mmu_gather.c | 4 +---
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
+index 71942a1c642d..c99710b3027a 100644
+--- a/include/asm-generic/tlb.h
++++ b/include/asm-generic/tlb.h
+@@ -207,12 +207,16 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+ #define tlb_needs_table_invalidate() (true)
+ #endif
+
++void tlb_remove_table_sync_one(void);
++
+ #else
+
+ #ifdef tlb_needs_table_invalidate
+ #error tlb_needs_table_invalidate() requires MMU_GATHER_RCU_TABLE_FREE
+ #endif
+
++static inline void tlb_remove_table_sync_one(void) { }
++
+ #endif /* CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+
+
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index fc02de08e912..1735123e462a 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -1156,6 +1156,7 @@ static void collapse_huge_page(struct mm_struct *mm,
+ _pmd = pmdp_collapse_flush(vma, address, pmd);
+ spin_unlock(pmd_ptl);
+ mmu_notifier_invalidate_range_end(&range);
++ tlb_remove_table_sync_one();
+
+ spin_lock(pte_ptl);
+ isolated = __collapse_huge_page_isolate(vma, address, pte,
+@@ -1537,6 +1538,7 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ /* step 4: collapse pmd */
+ _pmd = pmdp_collapse_flush(vma, haddr, pmd);
+ mm_dec_nr_ptes(mm);
++ tlb_remove_table_sync_one();
+ pte_free(mm, pmd_pgtable(_pmd));
+
+ i_mmap_unlock_write(vma->vm_file->f_mapping);
+@@ -1623,6 +1625,7 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
+ /* assume page table is clear */
+ _pmd = pmdp_collapse_flush(vma, addr, pmd);
+ mm_dec_nr_ptes(mm);
++ tlb_remove_table_sync_one();
+ pte_free(mm, pmd_pgtable(_pmd));
+ }
+ mmap_write_unlock(mm);
+diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c
+index 1b9837419bf9..8be26c7ddb47 100644
+--- a/mm/mmu_gather.c
++++ b/mm/mmu_gather.c
+@@ -139,7 +139,7 @@ static void tlb_remove_table_smp_sync(void *arg)
+ /* Simply deliver the interrupt */
+ }
+
+-static void tlb_remove_table_sync_one(void)
++void tlb_remove_table_sync_one(void)
+ {
+ /*
+ * This isn't an RCU grace period and hence the page-tables cannot be
+@@ -163,8 +163,6 @@ static void tlb_remove_table_free(struct mmu_table_batch *batch)
+
+ #else /* !CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+
+-static void tlb_remove_table_sync_one(void) { }
+-
+ static void tlb_remove_table_free(struct mmu_table_batch *batch)
+ {
+ __tlb_remove_table_free(batch);
+--
+2.35.1
+
--- /dev/null
+From 99dd036d2e5ec2f9fa0205dc336ecf2ff453bce2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 18:16:05 +0100
+Subject: mm/khugepaged: invoke MMU notifiers in shmem/file collapse paths
+
+From: Jann Horn <jannh@google.com>
+
+commit f268f6cf875f3220afc77bdd0bf1bb136eb54db9 upstream.
+
+Any codepath that zaps page table entries must invoke MMU notifiers to
+ensure that secondary MMUs (like KVM) don't keep accessing pages which
+aren't mapped anymore. Secondary MMUs don't hold their own references to
+pages that are mirrored over, so failing to notify them can lead to page
+use-after-free.
+
+I'm marking this as addressing an issue introduced in commit f3f0e1d2150b
+("khugepaged: add support of collapse for tmpfs/shmem pages"), but most of
+the security impact of this only came in commit 27e1f8273113 ("khugepaged:
+enable collapse pmd for pte-mapped THP"), which actually omitted flushes
+for the removal of present PTEs, not just for the removal of empty page
+tables.
+
+Link: https://lkml.kernel.org/r/20221129154730.2274278-3-jannh@google.com
+Link: https://lkml.kernel.org/r/20221128180252.1684965-3-jannh@google.com
+Link: https://lkml.kernel.org/r/20221125213714.4115729-3-jannh@google.com
+Fixes: f3f0e1d2150b ("khugepaged: add support of collapse for tmpfs/shmem pages")
+Signed-off-by: Jann Horn <jannh@google.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Yang Shi <shy828301@gmail.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[manual backport: this code was refactored from two copies into a common
+helper between 5.15 and 6.0]
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/khugepaged.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 1735123e462a..fd25d12e85b3 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -1443,6 +1443,7 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ spinlock_t *ptl;
+ int count = 0;
+ int i;
++ struct mmu_notifier_range range;
+
+ if (!vma || !vma->vm_file ||
+ !range_in_vma(vma, haddr, haddr + HPAGE_PMD_SIZE))
+@@ -1536,9 +1537,13 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ }
+
+ /* step 4: collapse pmd */
++ mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm, haddr,
++ haddr + HPAGE_PMD_SIZE);
++ mmu_notifier_invalidate_range_start(&range);
+ _pmd = pmdp_collapse_flush(vma, haddr, pmd);
+ mm_dec_nr_ptes(mm);
+ tlb_remove_table_sync_one();
++ mmu_notifier_invalidate_range_end(&range);
+ pte_free(mm, pmd_pgtable(_pmd));
+
+ i_mmap_unlock_write(vma->vm_file->f_mapping);
+@@ -1622,11 +1627,19 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
+ */
+ if (mmap_write_trylock(mm)) {
+ if (!khugepaged_test_exit(mm)) {
++ struct mmu_notifier_range range;
++
++ mmu_notifier_range_init(&range,
++ MMU_NOTIFY_CLEAR, 0,
++ NULL, mm, addr,
++ addr + HPAGE_PMD_SIZE);
++ mmu_notifier_invalidate_range_start(&range);
+ /* assume page table is clear */
+ _pmd = pmdp_collapse_flush(vma, addr, pmd);
+ mm_dec_nr_ptes(mm);
+ tlb_remove_table_sync_one();
+ pte_free(mm, pmd_pgtable(_pmd));
++ mmu_notifier_invalidate_range_end(&range);
+ }
+ mmap_write_unlock(mm);
+ } else {
+--
+2.35.1
+
--- /dev/null
+From d565a81c6d487424f5a90fe146291b561c14773b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 18:16:06 +0100
+Subject: mm/khugepaged: take the right locks for page table retraction
+
+From: Jann Horn <jannh@google.com>
+
+commit 8d3c106e19e8d251da31ff4cc7462e4565d65084 upstream.
+
+pagetable walks on address ranges mapped by VMAs can be done under the
+mmap lock, the lock of an anon_vma attached to the VMA, or the lock of the
+VMA's address_space. Only one of these needs to be held, and it does not
+need to be held in exclusive mode.
+
+Under those circumstances, the rules for concurrent access to page table
+entries are:
+
+ - Terminal page table entries (entries that don't point to another page
+ table) can be arbitrarily changed under the page table lock, with the
+ exception that they always need to be consistent for
+ hardware page table walks and lockless_pages_from_mm().
+ This includes that they can be changed into non-terminal entries.
+ - Non-terminal page table entries (which point to another page table)
+ can not be modified; readers are allowed to READ_ONCE() an entry, verify
+ that it is non-terminal, and then assume that its value will stay as-is.
+
+Retracting a page table involves modifying a non-terminal entry, so
+page-table-level locks are insufficient to protect against concurrent page
+table traversal; it requires taking all the higher-level locks under which
+it is possible to start a page walk in the relevant range in exclusive
+mode.
+
+The collapse_huge_page() path for anonymous THP already follows this rule,
+but the shmem/file THP path was getting it wrong, making it possible for
+concurrent rmap-based operations to cause corruption.
+
+Link: https://lkml.kernel.org/r/20221129154730.2274278-1-jannh@google.com
+Link: https://lkml.kernel.org/r/20221128180252.1684965-1-jannh@google.com
+Link: https://lkml.kernel.org/r/20221125213714.4115729-1-jannh@google.com
+Fixes: 27e1f8273113 ("khugepaged: enable collapse pmd for pte-mapped THP")
+Signed-off-by: Jann Horn <jannh@google.com>
+Reviewed-by: Yang Shi <shy828301@gmail.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[manual backport: this code was refactored from two copies into a common
+helper between 5.15 and 6.0]
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/khugepaged.c | 31 ++++++++++++++++++++++++++-----
+ 1 file changed, 26 insertions(+), 5 deletions(-)
+
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index dd069afd9cb9..fc02de08e912 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -1456,6 +1456,14 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ if (!hugepage_vma_check(vma, vma->vm_flags | VM_HUGEPAGE))
+ return;
+
++ /*
++ * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings
++ * that got written to. Without this, we'd have to also lock the
++ * anon_vma if one exists.
++ */
++ if (vma->anon_vma)
++ return;
++
+ hpage = find_lock_page(vma->vm_file->f_mapping,
+ linear_page_index(vma, haddr));
+ if (!hpage)
+@@ -1468,6 +1476,19 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ if (!pmd)
+ goto drop_hpage;
+
++ /*
++ * We need to lock the mapping so that from here on, only GUP-fast and
++ * hardware page walks can access the parts of the page tables that
++ * we're operating on.
++ */
++ i_mmap_lock_write(vma->vm_file->f_mapping);
++
++ /*
++ * This spinlock should be unnecessary: Nobody else should be accessing
++ * the page tables under spinlock protection here, only
++ * lockless_pages_from_mm() and the hardware page walker can access page
++ * tables while all the high-level locks are held in write mode.
++ */
+ start_pte = pte_offset_map_lock(mm, pmd, haddr, &ptl);
+
+ /* step 1: check all mapped PTEs are to the right huge page */
+@@ -1514,12 +1535,12 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ }
+
+ /* step 4: collapse pmd */
+- ptl = pmd_lock(vma->vm_mm, pmd);
+ _pmd = pmdp_collapse_flush(vma, haddr, pmd);
+- spin_unlock(ptl);
+ mm_dec_nr_ptes(mm);
+ pte_free(mm, pmd_pgtable(_pmd));
+
++ i_mmap_unlock_write(vma->vm_file->f_mapping);
++
+ drop_hpage:
+ unlock_page(hpage);
+ put_page(hpage);
+@@ -1527,6 +1548,7 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+
+ abort:
+ pte_unmap_unlock(start_pte, ptl);
++ i_mmap_unlock_write(vma->vm_file->f_mapping);
+ goto drop_hpage;
+ }
+
+@@ -1575,7 +1597,8 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
+ * An alternative would be drop the check, but check that page
+ * table is clear before calling pmdp_collapse_flush() under
+ * ptl. It has higher chance to recover THP for the VMA, but
+- * has higher cost too.
++ * has higher cost too. It would also probably require locking
++ * the anon_vma.
+ */
+ if (vma->anon_vma)
+ continue;
+@@ -1597,10 +1620,8 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
+ */
+ if (mmap_write_trylock(mm)) {
+ if (!khugepaged_test_exit(mm)) {
+- spinlock_t *ptl = pmd_lock(mm, pmd);
+ /* assume page table is clear */
+ _pmd = pmdp_collapse_flush(vma, addr, pmd);
+- spin_unlock(ptl);
+ mm_dec_nr_ptes(mm);
+ pte_free(mm, pmd_pgtable(_pmd));
+ }
+--
+2.35.1
+
--- /dev/null
+From d0ae18a75ad239738af5cbd3b85d0bddf1d3ef2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 17:01:41 +0800
+Subject: mmc: mtk-sd: Fix missing clk_disable_unprepare in
+ msdc_of_clock_parse()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit c61bfb1cb63ddab52b31cf5f1924688917e61fad ]
+
+The clk_disable_unprepare() should be called in the error handling
+of devm_clk_bulk_get_optional, fix it by replacing devm_clk_get_optional
+and clk_prepare_enable by devm_clk_get_optional_enabled.
+
+Fixes: f5eccd94b63f ("mmc: mediatek: Add subsys clock control for MT8192 msdc")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20221125090141.3626747-1-cuigaosheng1@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mtk-sd.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 99d8881a7d6c..9871c19d2b4e 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -2455,13 +2455,11 @@ static int msdc_of_clock_parse(struct platform_device *pdev,
+ if (IS_ERR(host->src_clk_cg))
+ host->src_clk_cg = NULL;
+
+- host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg");
++ /* If present, always enable for this clock gate */
++ host->sys_clk_cg = devm_clk_get_optional_enabled(&pdev->dev, "sys_cg");
+ if (IS_ERR(host->sys_clk_cg))
+ host->sys_clk_cg = NULL;
+
+- /* If present, always enable for this clock gate */
+- clk_prepare_enable(host->sys_clk_cg);
+-
+ host->bulk_clks[0].id = "pclk_cg";
+ host->bulk_clks[1].id = "axi_cg";
+ host->bulk_clks[2].id = "ahb_cg";
+--
+2.35.1
+
--- /dev/null
+From b1a8e9c82dd8d7f629ae021a9c605258cdb3220e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 13:54:55 +0100
+Subject: net: usb: qmi_wwan: add u-blox 0x1342 composition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Davide Tronchin <davide.tronchin.94@gmail.com>
+
+[ Upstream commit a487069e11b6527373f7c6f435d8998051d0b5d9 ]
+
+Add RmNet support for LARA-L6.
+
+LARA-L6 module can be configured (by AT interface) in three different
+USB modes:
+* Default mode (Vendor ID: 0x1546 Product ID: 0x1341) with 4 serial
+interfaces
+* RmNet mode (Vendor ID: 0x1546 Product ID: 0x1342) with 4 serial
+interfaces and 1 RmNet virtual network interface
+* CDC-ECM mode (Vendor ID: 0x1546 Product ID: 0x1343) with 4 serial
+interface and 1 CDC-ECM virtual network interface
+
+In RmNet mode LARA-L6 exposes the following interfaces:
+If 0: Diagnostic
+If 1: AT parser
+If 2: AT parser
+If 3: AT parset/alternative functions
+If 4: RMNET interface
+
+Signed-off-by: Davide Tronchin <davide.tronchin.94@gmail.com>
+Acked-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/qmi_wwan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index d886f903e428..7b358b896a6d 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1413,6 +1413,7 @@ static const struct usb_device_id products[] = {
+ {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */
+ {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/
+ {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
++ {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
+
+ /* 4. Gobi 1000 devices */
+ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
+--
+2.35.1
+
--- /dev/null
+From f3c72887845d9338870baca4d68740a033b8c5cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 14:10:35 +0100
+Subject: regulator: slg51000: Wait after asserting CS pin
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 0b24dfa587c6cc7484cfb170da5c7dd73451f670 ]
+
+Sony's downstream driver [1], among some other changes, adds a
+seemingly random 10ms usleep_range, which turned out to be necessary
+for the hardware to function properly on at least Sony Xperia 1 IV.
+Without this, I2C transactions with the SLG51000 straight up fail.
+
+Relax (10-10ms -> 10-11ms) and add the aforementioned sleep to make
+sure the hardware has some time to wake up.
+
+(nagara-2.0.0-mlc/vendor/semc/hardware/camera-kernel-module/)
+[1] https://developer.sony.com/file/download/open-source-archive-for-64-0-m-4-29/
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20221118131035.54874-1-konrad.dybcio@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/slg51000-regulator.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c
+index 75a941fb3c2b..1b2eee95ad3f 100644
+--- a/drivers/regulator/slg51000-regulator.c
++++ b/drivers/regulator/slg51000-regulator.c
+@@ -457,6 +457,8 @@ static int slg51000_i2c_probe(struct i2c_client *client)
+ chip->cs_gpiod = cs_gpiod;
+ }
+
++ usleep_range(10000, 11000);
++
+ i2c_set_clientdata(client, chip);
+ chip->chip_irq = client->irq;
+ chip->dev = dev;
+--
+2.35.1
+
--- /dev/null
+From 037ea6640a7d826fa4399ea0fbb142cec840e290 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 23:12:08 +0100
+Subject: regulator: twl6030: fix get status of twl6032 regulators
+
+From: Andreas Kemnade <andreas@kemnade.info>
+
+[ Upstream commit 31a6297b89aabc81b274c093a308a7f5b55081a7 ]
+
+Status is reported as always off in the 6032 case. Status
+reporting now matches the logic in the setters. Once of
+the differences to the 6030 is that there are no groups,
+therefore the state needs to be read out in the lower bits.
+
+Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
+Link: https://lore.kernel.org/r/20221120221208.3093727-3-andreas@kemnade.info
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/twl6030-regulator.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
+index 7c7e3648ea4b..f3856750944f 100644
+--- a/drivers/regulator/twl6030-regulator.c
++++ b/drivers/regulator/twl6030-regulator.c
+@@ -67,6 +67,7 @@ struct twlreg_info {
+ #define TWL6030_CFG_STATE_SLEEP 0x03
+ #define TWL6030_CFG_STATE_GRP_SHIFT 5
+ #define TWL6030_CFG_STATE_APP_SHIFT 2
++#define TWL6030_CFG_STATE_MASK 0x03
+ #define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT)
+ #define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
+ TWL6030_CFG_STATE_APP_SHIFT)
+@@ -128,13 +129,14 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev)
+ if (grp < 0)
+ return grp;
+ grp &= P1_GRP_6030;
++ val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
++ val = TWL6030_CFG_STATE_APP(val);
+ } else {
++ val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
++ val &= TWL6030_CFG_STATE_MASK;
+ grp = 1;
+ }
+
+- val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+- val = TWL6030_CFG_STATE_APP(val);
+-
+ return grp && (val == TWL6030_CFG_STATE_ON);
+ }
+
+@@ -187,7 +189,12 @@ static int twl6030reg_get_status(struct regulator_dev *rdev)
+
+ val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+
+- switch (TWL6030_CFG_STATE_APP(val)) {
++ if (info->features & TWL6032_SUBCLASS)
++ val &= TWL6030_CFG_STATE_MASK;
++ else
++ val = TWL6030_CFG_STATE_APP(val);
++
++ switch (val) {
+ case TWL6030_CFG_STATE_ON:
+ return REGULATOR_STATUS_NORMAL;
+
+--
+2.35.1
+
--- /dev/null
+From 50c4ea63dc5fc03ba9513c0d72cf1032d69ab2d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Dec 2021 21:01:30 +0100
+Subject: rtc: cmos: avoid UIP when reading alarm time
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mateusz Jończyk <mat.jonczyk@o2.pl>
+
+[ Upstream commit cdedc45c579faf8cc6608d3ef81576ee0d512aa4 ]
+
+Some Intel chipsets disconnect the time and date RTC registers when the
+clock update is in progress: during this time reads may return bogus
+values and writes fail silently. This includes the RTC alarm registers.
+[1]
+
+cmos_read_alarm() did not take account for that, which caused alarm time
+reads to sometimes return bogus values. This can be shown with a test
+patch that I am attaching to this patch series.
+
+Fix this, by using mc146818_avoid_UIP().
+
+[1] 7th Generation Intel ® Processor Family I/O for U/Y Platforms [...]
+Datasheet, Volume 1 of 2 (Intel's Document Number: 334658-006)
+Page 208
+https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/7th-and-8th-gen-core-family-mobile-u-y-processor-lines-i-o-datasheet-vol-1.pdf
+ "If a RAM read from the ten time and date bytes is attempted
+ during an update cycle, the value read do not necessarily
+ represent the true contents of those locations. Any RAM writes
+ under the same conditions are ignored."
+
+Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
+Cc: Alessandro Zummo <a.zummo@towertech.it>
+Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20211210200131.153887-9-mat.jonczyk@o2.pl
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 72 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 49 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index a3297a9cbc59..7c006c2b125f 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -249,10 +249,46 @@ static int cmos_set_time(struct device *dev, struct rtc_time *t)
+ return mc146818_set_time(t);
+ }
+
++struct cmos_read_alarm_callback_param {
++ struct cmos_rtc *cmos;
++ struct rtc_time *time;
++ unsigned char rtc_control;
++};
++
++static void cmos_read_alarm_callback(unsigned char __always_unused seconds,
++ void *param_in)
++{
++ struct cmos_read_alarm_callback_param *p =
++ (struct cmos_read_alarm_callback_param *)param_in;
++ struct rtc_time *time = p->time;
++
++ time->tm_sec = CMOS_READ(RTC_SECONDS_ALARM);
++ time->tm_min = CMOS_READ(RTC_MINUTES_ALARM);
++ time->tm_hour = CMOS_READ(RTC_HOURS_ALARM);
++
++ if (p->cmos->day_alrm) {
++ /* ignore upper bits on readback per ACPI spec */
++ time->tm_mday = CMOS_READ(p->cmos->day_alrm) & 0x3f;
++ if (!time->tm_mday)
++ time->tm_mday = -1;
++
++ if (p->cmos->mon_alrm) {
++ time->tm_mon = CMOS_READ(p->cmos->mon_alrm);
++ if (!time->tm_mon)
++ time->tm_mon = -1;
++ }
++ }
++
++ p->rtc_control = CMOS_READ(RTC_CONTROL);
++}
++
+ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
+ {
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+- unsigned char rtc_control;
++ struct cmos_read_alarm_callback_param p = {
++ .cmos = cmos,
++ .time = &t->time,
++ };
+
+ /* This not only a rtc_op, but also called directly */
+ if (!is_valid_irq(cmos->irq))
+@@ -263,28 +299,18 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
+ * the future.
+ */
+
+- spin_lock_irq(&rtc_lock);
+- t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM);
+- t->time.tm_min = CMOS_READ(RTC_MINUTES_ALARM);
+- t->time.tm_hour = CMOS_READ(RTC_HOURS_ALARM);
+-
+- if (cmos->day_alrm) {
+- /* ignore upper bits on readback per ACPI spec */
+- t->time.tm_mday = CMOS_READ(cmos->day_alrm) & 0x3f;
+- if (!t->time.tm_mday)
+- t->time.tm_mday = -1;
+-
+- if (cmos->mon_alrm) {
+- t->time.tm_mon = CMOS_READ(cmos->mon_alrm);
+- if (!t->time.tm_mon)
+- t->time.tm_mon = -1;
+- }
+- }
+-
+- rtc_control = CMOS_READ(RTC_CONTROL);
+- spin_unlock_irq(&rtc_lock);
++ /* Some Intel chipsets disconnect the alarm registers when the clock
++ * update is in progress - during this time reads return bogus values
++ * and writes may fail silently. See for example "7th Generation Intel®
++ * Processor Family I/O for U/Y Platforms [...] Datasheet", section
++ * 27.7.1
++ *
++ * Use the mc146818_avoid_UIP() function to avoid this.
++ */
++ if (!mc146818_avoid_UIP(cmos_read_alarm_callback, &p))
++ return -EIO;
+
+- if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
++ if (!(p.rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ if (((unsigned)t->time.tm_sec) < 0x60)
+ t->time.tm_sec = bcd2bin(t->time.tm_sec);
+ else
+@@ -313,7 +339,7 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
+ }
+ }
+
+- t->enabled = !!(rtc_control & RTC_AIE);
++ t->enabled = !!(p.rtc_control & RTC_AIE);
+ t->pending = 0;
+
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From d323e83d37574e3e51e333baa05001e0ac6e129a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Dec 2021 21:01:31 +0100
+Subject: rtc: cmos: avoid UIP when writing alarm time
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mateusz Jończyk <mat.jonczyk@o2.pl>
+
+[ Upstream commit cd17420ebea580c22dd3a93f7237de3d2cfafc37 ]
+
+Some Intel chipsets disconnect the time and date RTC registers when the
+clock update is in progress: during this time reads may return bogus
+values and writes fail silently. This includes the RTC alarm registers.
+[1]
+
+cmos_set_alarm() did not take account for that, fix it.
+
+[1] 7th Generation Intel ® Processor Family I/O for U/Y Platforms [...]
+Datasheet, Volume 1 of 2 (Intel's Document Number: 334658-006)
+Page 208
+https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/7th-and-8th-gen-core-family-mobile-u-y-processor-lines-i-o-datasheet-vol-1.pdf
+ "If a RAM read from the ten time and date bytes is attempted
+ during an update cycle, the value read do not necessarily
+ represent the true contents of those locations. Any RAM writes
+ under the same conditions are ignored."
+
+Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
+Cc: Alessandro Zummo <a.zummo@towertech.it>
+Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20211210200131.153887-10-mat.jonczyk@o2.pl
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-cmos.c | 107 +++++++++++++++++++++++++----------------
+ 1 file changed, 66 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index b90a603d6b12..a3297a9cbc59 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -444,10 +444,57 @@ static int cmos_validate_alarm(struct device *dev, struct rtc_wkalrm *t)
+ return 0;
+ }
+
++struct cmos_set_alarm_callback_param {
++ struct cmos_rtc *cmos;
++ unsigned char mon, mday, hrs, min, sec;
++ struct rtc_wkalrm *t;
++};
++
++/* Note: this function may be executed by mc146818_avoid_UIP() more then
++ * once
++ */
++static void cmos_set_alarm_callback(unsigned char __always_unused seconds,
++ void *param_in)
++{
++ struct cmos_set_alarm_callback_param *p =
++ (struct cmos_set_alarm_callback_param *)param_in;
++
++ /* next rtc irq must not be from previous alarm setting */
++ cmos_irq_disable(p->cmos, RTC_AIE);
++
++ /* update alarm */
++ CMOS_WRITE(p->hrs, RTC_HOURS_ALARM);
++ CMOS_WRITE(p->min, RTC_MINUTES_ALARM);
++ CMOS_WRITE(p->sec, RTC_SECONDS_ALARM);
++
++ /* the system may support an "enhanced" alarm */
++ if (p->cmos->day_alrm) {
++ CMOS_WRITE(p->mday, p->cmos->day_alrm);
++ if (p->cmos->mon_alrm)
++ CMOS_WRITE(p->mon, p->cmos->mon_alrm);
++ }
++
++ if (use_hpet_alarm()) {
++ /*
++ * FIXME the HPET alarm glue currently ignores day_alrm
++ * and mon_alrm ...
++ */
++ hpet_set_alarm_time(p->t->time.tm_hour, p->t->time.tm_min,
++ p->t->time.tm_sec);
++ }
++
++ if (p->t->enabled)
++ cmos_irq_enable(p->cmos, RTC_AIE);
++}
++
+ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
+ {
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+- unsigned char mon, mday, hrs, min, sec, rtc_control;
++ struct cmos_set_alarm_callback_param p = {
++ .cmos = cmos,
++ .t = t
++ };
++ unsigned char rtc_control;
+ int ret;
+
+ /* This not only a rtc_op, but also called directly */
+@@ -458,11 +505,11 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
+ if (ret < 0)
+ return ret;
+
+- mon = t->time.tm_mon + 1;
+- mday = t->time.tm_mday;
+- hrs = t->time.tm_hour;
+- min = t->time.tm_min;
+- sec = t->time.tm_sec;
++ p.mon = t->time.tm_mon + 1;
++ p.mday = t->time.tm_mday;
++ p.hrs = t->time.tm_hour;
++ p.min = t->time.tm_min;
++ p.sec = t->time.tm_sec;
+
+ spin_lock_irq(&rtc_lock);
+ rtc_control = CMOS_READ(RTC_CONTROL);
+@@ -470,43 +517,21 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
+
+ if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ /* Writing 0xff means "don't care" or "match all". */
+- mon = (mon <= 12) ? bin2bcd(mon) : 0xff;
+- mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff;
+- hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff;
+- min = (min < 60) ? bin2bcd(min) : 0xff;
+- sec = (sec < 60) ? bin2bcd(sec) : 0xff;
++ p.mon = (p.mon <= 12) ? bin2bcd(p.mon) : 0xff;
++ p.mday = (p.mday >= 1 && p.mday <= 31) ? bin2bcd(p.mday) : 0xff;
++ p.hrs = (p.hrs < 24) ? bin2bcd(p.hrs) : 0xff;
++ p.min = (p.min < 60) ? bin2bcd(p.min) : 0xff;
++ p.sec = (p.sec < 60) ? bin2bcd(p.sec) : 0xff;
+ }
+
+- spin_lock_irq(&rtc_lock);
+-
+- /* next rtc irq must not be from previous alarm setting */
+- cmos_irq_disable(cmos, RTC_AIE);
+-
+- /* update alarm */
+- CMOS_WRITE(hrs, RTC_HOURS_ALARM);
+- CMOS_WRITE(min, RTC_MINUTES_ALARM);
+- CMOS_WRITE(sec, RTC_SECONDS_ALARM);
+-
+- /* the system may support an "enhanced" alarm */
+- if (cmos->day_alrm) {
+- CMOS_WRITE(mday, cmos->day_alrm);
+- if (cmos->mon_alrm)
+- CMOS_WRITE(mon, cmos->mon_alrm);
+- }
+-
+- if (use_hpet_alarm()) {
+- /*
+- * FIXME the HPET alarm glue currently ignores day_alrm
+- * and mon_alrm ...
+- */
+- hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min,
+- t->time.tm_sec);
+- }
+-
+- if (t->enabled)
+- cmos_irq_enable(cmos, RTC_AIE);
+-
+- spin_unlock_irq(&rtc_lock);
++ /*
++ * Some Intel chipsets disconnect the alarm registers when the clock
++ * update is in progress - during this time writes fail silently.
++ *
++ * Use mc146818_avoid_UIP() to avoid this.
++ */
++ if (!mc146818_avoid_UIP(cmos_set_alarm_callback, &p))
++ return -EIO;
+
+ cmos->alarm_expires = rtc_tm_to_time64(&t->time);
+
+--
+2.35.1
+
--- /dev/null
+From b7a4422f9f251c9b608710cba6af7fab38523489 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Dec 2021 21:01:27 +0100
+Subject: rtc: mc146818-lib: extract mc146818_avoid_UIP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mateusz Jończyk <mat.jonczyk@o2.pl>
+
+[ Upstream commit ec5895c0f2d87b9bf4185db1915e40fa6fcfc0ac ]
+
+Function mc146818_get_time() contains an elaborate mechanism of reading
+the RTC time while no RTC update is in progress. It turns out that
+reading the RTC alarm clock also requires avoiding the RTC update.
+Therefore, the mechanism in mc146818_get_time() should be reused - so
+extract it into a separate function.
+
+The logic in mc146818_avoid_UIP() is same as in mc146818_get_time()
+except that after every
+
+ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
+
+there is now "mdelay(1)".
+
+To avoid producing a very unreadable patch, mc146818_get_time() will be
+refactored to use mc146818_avoid_UIP() in the next patch.
+
+Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
+Cc: Alessandro Zummo <a.zummo@towertech.it>
+Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20211210200131.153887-6-mat.jonczyk@o2.pl
+Stable-dep-of: cd17420ebea5 ("rtc: cmos: avoid UIP when writing alarm time")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-mc146818-lib.c | 70 ++++++++++++++++++++++++++++++++++
+ include/linux/mc146818rtc.h | 3 ++
+ 2 files changed, 73 insertions(+)
+
+diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c
+index f3f5a87fe376..347655d24b5d 100644
+--- a/drivers/rtc/rtc-mc146818-lib.c
++++ b/drivers/rtc/rtc-mc146818-lib.c
+@@ -8,6 +8,76 @@
+ #include <linux/acpi.h>
+ #endif
+
++/*
++ * Execute a function while the UIP (Update-in-progress) bit of the RTC is
++ * unset.
++ *
++ * Warning: callback may be executed more then once.
++ */
++bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
++ void *param)
++{
++ int i;
++ unsigned long flags;
++ unsigned char seconds;
++
++ for (i = 0; i < 10; i++) {
++ spin_lock_irqsave(&rtc_lock, flags);
++
++ /*
++ * Check whether there is an update in progress during which the
++ * readout is unspecified. The maximum update time is ~2ms. Poll
++ * every msec for completion.
++ *
++ * Store the second value before checking UIP so a long lasting
++ * NMI which happens to hit after the UIP check cannot make
++ * an update cycle invisible.
++ */
++ seconds = CMOS_READ(RTC_SECONDS);
++
++ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
++ spin_unlock_irqrestore(&rtc_lock, flags);
++ mdelay(1);
++ continue;
++ }
++
++ /* Revalidate the above readout */
++ if (seconds != CMOS_READ(RTC_SECONDS)) {
++ spin_unlock_irqrestore(&rtc_lock, flags);
++ continue;
++ }
++
++ if (callback)
++ callback(seconds, param);
++
++ /*
++ * Check for the UIP bit again. If it is set now then
++ * the above values may contain garbage.
++ */
++ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
++ spin_unlock_irqrestore(&rtc_lock, flags);
++ mdelay(1);
++ continue;
++ }
++
++ /*
++ * A NMI might have interrupted the above sequence so check
++ * whether the seconds value has changed which indicates that
++ * the NMI took longer than the UIP bit was set. Unlikely, but
++ * possible and there is also virt...
++ */
++ if (seconds != CMOS_READ(RTC_SECONDS)) {
++ spin_unlock_irqrestore(&rtc_lock, flags);
++ continue;
++ }
++ spin_unlock_irqrestore(&rtc_lock, flags);
++
++ return true;
++ }
++ return false;
++}
++EXPORT_SYMBOL_GPL(mc146818_avoid_UIP);
++
+ /*
+ * If the UIP (Update-in-progress) bit of the RTC is set for more then
+ * 10ms, the RTC is apparently broken or not present.
+diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
+index 3038124c6115..b0da04fe087b 100644
+--- a/include/linux/mc146818rtc.h
++++ b/include/linux/mc146818rtc.h
+@@ -129,4 +129,7 @@ bool mc146818_does_rtc_work(void);
+ int mc146818_get_time(struct rtc_time *time);
+ int mc146818_set_time(struct rtc_time *time);
+
++bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
++ void *param);
++
+ #endif /* _MC146818RTC_H */
+--
+2.35.1
+
--- /dev/null
+From ee66e69adf49d0b70c6047f373021590d86b0d79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 21:44:21 -0600
+Subject: selftests/net: Find nettest in current directory
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel DÃaz <daniel.diaz@linaro.org>
+
+[ Upstream commit bd5e1e42826f18147afb0ba07e6a815f52cf8bcb ]
+
+The `nettest` binary, built from `selftests/net/nettest.c`,
+was expected to be found in the path during test execution of
+`fcnal-test.sh` and `pmtu.sh`, leading to tests getting
+skipped when the binary is not installed in the system, as can
+be seen in these logs found in the wild [1]:
+
+ # TEST: vti4: PMTU exceptions [SKIP]
+ [ 350.600250] IPv6: ADDRCONF(NETDEV_CHANGE): veth_b: link becomes ready
+ [ 350.607421] IPv6: ADDRCONF(NETDEV_CHANGE): veth_a: link becomes ready
+ # 'nettest' command not found; skipping tests
+ # xfrm6udp not supported
+ # TEST: vti6: PMTU exceptions (ESP-in-UDP) [SKIP]
+ [ 351.605102] IPv6: ADDRCONF(NETDEV_CHANGE): veth_b: link becomes ready
+ [ 351.612243] IPv6: ADDRCONF(NETDEV_CHANGE): veth_a: link becomes ready
+ # 'nettest' command not found; skipping tests
+ # xfrm4udp not supported
+
+The `unicast_extensions.sh` tests also rely on `nettest`, but
+it runs fine there because it looks for the binary in the
+current working directory [2]:
+
+The same mechanism that works for the Unicast extensions tests
+is here copied over to the PMTU and functional tests.
+
+[1] https://lkft.validation.linaro.org/scheduler/job/5839508#L6221
+[2] https://lkft.validation.linaro.org/scheduler/job/5839508#L7958
+
+Signed-off-by: Daniel DÃaz <daniel.diaz@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/fcnal-test.sh | 11 +++++++----
+ tools/testing/selftests/net/pmtu.sh | 10 ++++++----
+ 2 files changed, 13 insertions(+), 8 deletions(-)
+
+diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh
+index 91f54112167f..364c82b797c1 100755
+--- a/tools/testing/selftests/net/fcnal-test.sh
++++ b/tools/testing/selftests/net/fcnal-test.sh
+@@ -4072,10 +4072,13 @@ elif [ "$TESTS" = "ipv6" ]; then
+ TESTS="$TESTS_IPV6"
+ fi
+
+-which nettest >/dev/null
+-if [ $? -ne 0 ]; then
+- echo "'nettest' command not found; skipping tests"
+- exit $ksft_skip
++# nettest can be run from PATH or from same directory as this selftest
++if ! which nettest >/dev/null; then
++ PATH=$PWD:$PATH
++ if ! which nettest >/dev/null; then
++ echo "'nettest' command not found; skipping tests"
++ exit $ksft_skip
++ fi
+ fi
+
+ declare -i nfail=0
+diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
+index 694732e4b344..da6ab300207c 100755
+--- a/tools/testing/selftests/net/pmtu.sh
++++ b/tools/testing/selftests/net/pmtu.sh
+@@ -671,10 +671,12 @@ setup_xfrm() {
+ }
+
+ setup_nettest_xfrm() {
+- which nettest >/dev/null
+- if [ $? -ne 0 ]; then
+- echo "'nettest' command not found; skipping tests"
+- return 1
++ if ! which nettest >/dev/null; then
++ PATH=$PWD:$PATH
++ if ! which nettest >/dev/null; then
++ echo "'nettest' command not found; skipping tests"
++ return 1
++ fi
+ fi
+
+ [ ${1} -eq 6 ] && proto="-6" || proto=""
+--
+2.35.1
+
--- /dev/null
+clk-generalize-devm_clk_get-a-bit.patch
+clk-provide-new-devm_clk-helpers-for-prepared-and-en.patch
+mmc-mtk-sd-fix-missing-clk_disable_unprepare-in-msdc.patch
+arm64-dts-rockchip-keep-i2s1-disabled-for-gpio-funct.patch
+arm-dts-rockchip-fix-node-name-for-hym8563-rtc.patch
+arm-dts-rockchip-remove-clock-frequency-from-rtc.patch
+arm-dts-rockchip-fix-ir-receiver-node-names.patch
+arm64-dts-rockchip-fix-ir-receiver-node-names.patch
+arm-dts-rockchip-rk3188-fix-lcdc1-rgb24-node-name.patch
+fs-use-acquire-ordering-in-__fget_light.patch
+arm-9251-1-perf-fix-stacktraces-for-tracepoint-event.patch
+arm-9266-1-mm-fix-no-mmu-zero_page-implementation.patch
+asoc-wm8962-wait-for-updated-value-of-wm8962_clockin.patch
+spi-mediatek-fix-devapc-violation-at-ko-remove.patch
+arm-dts-rockchip-disable-arm_global_timer-on-rk3066-.patch
+asoc-rt711-sdca-fix-the-latency-time-of-clock-stop-p.patch
+9p-fd-use-p9_hdrsz-for-header-size.patch
+regulator-slg51000-wait-after-asserting-cs-pin.patch
+alsa-seq-fix-function-prototype-mismatch-in-snd_seq_.patch
+selftests-net-find-nettest-in-current-directory.patch
+btrfs-send-avoid-unaligned-encoded-writes-when-attem.patch
+asoc-soc-pcm-add-null-check-in-be-reparenting.patch
+regulator-twl6030-fix-get-status-of-twl6032-regulato.patch
+fbcon-use-kzalloc-in-fbcon_prepare_logo.patch
+usb-dwc3-gadget-disable-gusb2phycfg.susphy-for-end-t.patch
+9p-xen-check-logical-size-for-buffer-size.patch
+net-usb-qmi_wwan-add-u-blox-0x1342-composition.patch
+mm-khugepaged-take-the-right-locks-for-page-table-re.patch
+mm-khugepaged-fix-gup-fast-interaction-by-sending-ip.patch
+mm-khugepaged-invoke-mmu-notifiers-in-shmem-file-col.patch
+rtc-mc146818-lib-extract-mc146818_avoid_uip.patch
+rtc-cmos-avoid-uip-when-writing-alarm-time.patch
+rtc-cmos-avoid-uip-when-reading-alarm-time.patch
+cifs-fix-use-after-free-caused-by-invalid-pointer-ho.patch
+drm-bridge-anx7625-fix-edid_read-break-case-in-sp_tx.patch
+xen-netback-ensure-protocol-headers-don-t-fall-in-th.patch
+xen-netback-do-some-code-cleanup.patch
+xen-netback-don-t-call-kfree_skb-with-interrupts-dis.patch
+media-videobuf2-core-take-mmap_lock-in-vb2_get_unmap.patch
--- /dev/null
+From ddb9f1bf0ea7d86add91a26b10b18424082b9e0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 15:28:39 +0800
+Subject: spi: mediatek: Fix DEVAPC Violation at KO Remove
+
+From: Zhichao Liu <zhichao.liu@mediatek.com>
+
+[ Upstream commit 0d10e90cee9eb57882b0f7e19fd699033722e226 ]
+
+A DEVAPC violation occurs when removing the module
+due to accessing HW registers without base clock.
+To fix this bug, the correct method is:
+1. Call the runtime resume function to enable the
+ clock;
+2. Operate the registers to reset the HW;
+3. Turn off the clocks and disable the device
+ RPM mechanism.
+
+Signed-off-by: Zhichao Liu <zhichao.liu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221110072839.30961-1-zhichao.liu@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mt65xx.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 2ca19b01948a..49acba1dea1e 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -912,14 +912,20 @@ static int mtk_spi_remove(struct platform_device *pdev)
+ {
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct mtk_spi *mdata = spi_master_get_devdata(master);
++ int ret;
+
+- pm_runtime_disable(&pdev->dev);
++ ret = pm_runtime_resume_and_get(&pdev->dev);
++ if (ret < 0)
++ return ret;
+
+ mtk_spi_reset(mdata);
+
+ if (mdata->dev_comp->no_need_unprepare)
+ clk_unprepare(mdata->spi_clk);
+
++ pm_runtime_put_noidle(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 470b9634aa9a05ba13d926c96993581a8cf40842 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 17:58:50 -0800
+Subject: usb: dwc3: gadget: Disable GUSB2PHYCFG.SUSPHY for End Transfer
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+[ Upstream commit 3aa07f72894d209fcf922ad686cbb28cf005aaad ]
+
+If there's a disconnection while operating in eSS, there may be a delay
+in VBUS drop response from the connector. In that case, the internal
+link state may drop to operate in usb2 speed while the controller thinks
+the VBUS is still high. The driver must make sure to disable
+GUSB2PHYCFG.SUSPHY when sending endpoint command while in usb2 speed.
+The End Transfer command may be called, and only that command needs to
+go through at this point. Let's keep it simple and unconditionally
+disable GUSB2PHYCFG.SUSPHY whenever we issue the command.
+
+This scenario is not seen in real hardware. In a rare case, our
+prototype type-c controller/interface may have a slow response
+triggerring this issue.
+
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/5651117207803c26e2f22ddf4e5ce9e865dcf7c7.1668045468.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index dfa1d9eedde1..4812ba4bbedd 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -291,7 +291,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
+ *
+ * DWC_usb3 3.30a and DWC_usb31 1.90a programming guide section 3.2.2
+ */
+- if (dwc->gadget->speed <= USB_SPEED_HIGH) {
++ if (dwc->gadget->speed <= USB_SPEED_HIGH ||
++ DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
+ saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
+--
+2.35.1
+
--- /dev/null
+From 2d5d8664056544b5f5a9e8a93dff0ebc44a6ff39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 06:37:26 +0200
+Subject: xen/netback: do some code cleanup
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 5834e72eda0b7e5767eb107259d98eef19ebd11f ]
+
+Remove some unused macros and functions, make local functions static.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Acked-by: Wei Liu <wei.liu@kernel.org>
+Link: https://lore.kernel.org/r/20220608043726.9380-1-jgross@suse.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 74e7e1efdad4 ("xen/netback: don't call kfree_skb() with interrupts disabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/common.h | 12 ------------
+ drivers/net/xen-netback/interface.c | 16 +---------------
+ drivers/net/xen-netback/netback.c | 4 +++-
+ drivers/net/xen-netback/rx.c | 2 +-
+ 4 files changed, 5 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
+index d9dea4829c86..8174d7b2966c 100644
+--- a/drivers/net/xen-netback/common.h
++++ b/drivers/net/xen-netback/common.h
+@@ -48,7 +48,6 @@
+ #include <linux/debugfs.h>
+
+ typedef unsigned int pending_ring_idx_t;
+-#define INVALID_PENDING_RING_IDX (~0U)
+
+ struct pending_tx_info {
+ struct xen_netif_tx_request req; /* tx request */
+@@ -82,8 +81,6 @@ struct xenvif_rx_meta {
+ /* Discriminate from any valid pending_idx value. */
+ #define INVALID_PENDING_IDX 0xFFFF
+
+-#define MAX_BUFFER_OFFSET XEN_PAGE_SIZE
+-
+ #define MAX_PENDING_REQS XEN_NETIF_TX_RING_SIZE
+
+ /* The maximum number of frags is derived from the size of a grant (same
+@@ -367,11 +364,6 @@ void xenvif_free(struct xenvif *vif);
+ int xenvif_xenbus_init(void);
+ void xenvif_xenbus_fini(void);
+
+-int xenvif_schedulable(struct xenvif *vif);
+-
+-int xenvif_queue_stopped(struct xenvif_queue *queue);
+-void xenvif_wake_queue(struct xenvif_queue *queue);
+-
+ /* (Un)Map communication rings. */
+ void xenvif_unmap_frontend_data_rings(struct xenvif_queue *queue);
+ int xenvif_map_frontend_data_rings(struct xenvif_queue *queue,
+@@ -394,7 +386,6 @@ int xenvif_dealloc_kthread(void *data);
+ irqreturn_t xenvif_ctrl_irq_fn(int irq, void *data);
+
+ bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread);
+-void xenvif_rx_action(struct xenvif_queue *queue);
+ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
+
+ void xenvif_carrier_on(struct xenvif *vif);
+@@ -403,9 +394,6 @@ void xenvif_carrier_on(struct xenvif *vif);
+ void xenvif_zerocopy_callback(struct sk_buff *skb, struct ubuf_info *ubuf,
+ bool zerocopy_success);
+
+-/* Unmap a pending page and release it back to the guest */
+-void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx);
+-
+ static inline pending_ring_idx_t nr_pending_reqs(struct xenvif_queue *queue)
+ {
+ return MAX_PENDING_REQS -
+diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
+index c58996c1e230..e31936876e1f 100644
+--- a/drivers/net/xen-netback/interface.c
++++ b/drivers/net/xen-netback/interface.c
+@@ -70,7 +70,7 @@ void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue)
+ wake_up(&queue->dealloc_wq);
+ }
+
+-int xenvif_schedulable(struct xenvif *vif)
++static int xenvif_schedulable(struct xenvif *vif)
+ {
+ return netif_running(vif->dev) &&
+ test_bit(VIF_STATUS_CONNECTED, &vif->status) &&
+@@ -178,20 +178,6 @@ irqreturn_t xenvif_interrupt(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
+-int xenvif_queue_stopped(struct xenvif_queue *queue)
+-{
+- struct net_device *dev = queue->vif->dev;
+- unsigned int id = queue->id;
+- return netif_tx_queue_stopped(netdev_get_tx_queue(dev, id));
+-}
+-
+-void xenvif_wake_queue(struct xenvif_queue *queue)
+-{
+- struct net_device *dev = queue->vif->dev;
+- unsigned int id = queue->id;
+- netif_tx_wake_queue(netdev_get_tx_queue(dev, id));
+-}
+-
+ static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb,
+ struct net_device *sb_dev)
+ {
+diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
+index a5c26772ec1f..6bd7b62fb90c 100644
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -112,6 +112,8 @@ static void make_tx_response(struct xenvif_queue *queue,
+ s8 st);
+ static void push_tx_responses(struct xenvif_queue *queue);
+
++static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx);
++
+ static inline int tx_work_todo(struct xenvif_queue *queue);
+
+ static inline unsigned long idx_to_pfn(struct xenvif_queue *queue,
+@@ -1441,7 +1443,7 @@ static void push_tx_responses(struct xenvif_queue *queue)
+ notify_remote_via_irq(queue->tx_irq);
+ }
+
+-void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
++static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
+ {
+ int ret;
+ struct gnttab_unmap_grant_ref tx_unmap_op;
+diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
+index a0335407be42..932762177110 100644
+--- a/drivers/net/xen-netback/rx.c
++++ b/drivers/net/xen-netback/rx.c
+@@ -486,7 +486,7 @@ static void xenvif_rx_skb(struct xenvif_queue *queue)
+
+ #define RX_BATCH_SIZE 64
+
+-void xenvif_rx_action(struct xenvif_queue *queue)
++static void xenvif_rx_action(struct xenvif_queue *queue)
+ {
+ struct sk_buff_head completed_skbs;
+ unsigned int work_done = 0;
+--
+2.35.1
+
--- /dev/null
+From 2cf789e793413350ca8101d0da292b8eb4f1b8a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 08:54:24 +0100
+Subject: xen/netback: don't call kfree_skb() with interrupts disabled
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 74e7e1efdad45580cc3839f2a155174cf158f9b5 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So remove kfree_skb()
+from the spin_lock_irqsave() section and use the already existing
+"drop" label in xenvif_start_xmit() for dropping the SKB. At the
+same time replace the dev_kfree_skb() call there with a call of
+dev_kfree_skb_any(), as xenvif_start_xmit() can be called with
+disabled interrupts.
+
+This is XSA-424 / CVE-2022-42328 / CVE-2022-42329.
+
+Fixes: be81992f9086 ("xen/netback: don't queue unlimited number of packages")
+Reported-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/common.h | 2 +-
+ drivers/net/xen-netback/interface.c | 6 ++++--
+ drivers/net/xen-netback/rx.c | 8 +++++---
+ 3 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
+index 8174d7b2966c..adfd21aa5b6a 100644
+--- a/drivers/net/xen-netback/common.h
++++ b/drivers/net/xen-netback/common.h
+@@ -386,7 +386,7 @@ int xenvif_dealloc_kthread(void *data);
+ irqreturn_t xenvif_ctrl_irq_fn(int irq, void *data);
+
+ bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread);
+-void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
++bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
+
+ void xenvif_carrier_on(struct xenvif *vif);
+
+diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
+index e31936876e1f..e1a5610b1747 100644
+--- a/drivers/net/xen-netback/interface.c
++++ b/drivers/net/xen-netback/interface.c
+@@ -255,14 +255,16 @@ xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)
+ skb_clear_hash(skb);
+
+- xenvif_rx_queue_tail(queue, skb);
++ if (!xenvif_rx_queue_tail(queue, skb))
++ goto drop;
++
+ xenvif_kick_thread(queue);
+
+ return NETDEV_TX_OK;
+
+ drop:
+ vif->dev->stats.tx_dropped++;
+- dev_kfree_skb(skb);
++ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
+index 932762177110..0ba754ebc5ba 100644
+--- a/drivers/net/xen-netback/rx.c
++++ b/drivers/net/xen-netback/rx.c
+@@ -82,9 +82,10 @@ static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue)
+ return false;
+ }
+
+-void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
++bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ {
+ unsigned long flags;
++ bool ret = true;
+
+ spin_lock_irqsave(&queue->rx_queue.lock, flags);
+
+@@ -92,8 +93,7 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ struct net_device *dev = queue->vif->dev;
+
+ netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));
+- kfree_skb(skb);
+- queue->vif->dev->stats.rx_dropped++;
++ ret = false;
+ } else {
+ if (skb_queue_empty(&queue->rx_queue))
+ xenvif_update_needed_slots(queue, skb);
+@@ -104,6 +104,8 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ }
+
+ spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
++
++ return ret;
+ }
+
+ static struct sk_buff *xenvif_rx_dequeue(struct xenvif_queue *queue)
+--
+2.35.1
+
--- /dev/null
+From 51a1378304ea0999576945c8b9d304c1465cfdcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 09:16:59 +0000
+Subject: xen/netback: Ensure protocol headers don't fall in the non-linear
+ area
+
+From: Ross Lagerwall <ross.lagerwall@citrix.com>
+
+[ Upstream commit ad7f402ae4f466647c3a669b8a6f3e5d4271c84a ]
+
+In some cases, the frontend may send a packet where the protocol headers
+are spread across multiple slots. This would result in netback creating
+an skb where the protocol headers spill over into the non-linear area.
+Some drivers and NICs don't handle this properly resulting in an
+interface reset or worse.
+
+This issue was introduced by the removal of an unconditional skb pull in
+the tx path to improve performance. Fix this without reintroducing the
+pull by setting up grant copy ops for as many slots as needed to reach
+the XEN_NETBACK_TX_COPY_LEN size. Adjust the rest of the code to handle
+multiple copy operations per skb.
+
+This is XSA-423 / CVE-2022-3643.
+
+Fixes: 7e5d7753956b ("xen-netback: remove unconditional __pskb_pull_tail() in guest Tx path")
+Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
+Reviewed-by: Paul Durrant <paul@xen.org>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/netback.c | 223 ++++++++++++++++--------------
+ 1 file changed, 123 insertions(+), 100 deletions(-)
+
+diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
+index 32d5bc4919d8..a5c26772ec1f 100644
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -330,10 +330,13 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
+
+
+ struct xenvif_tx_cb {
+- u16 pending_idx;
++ u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1];
++ u8 copy_count;
+ };
+
+ #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb)
++#define copy_pending_idx(skb, i) (XENVIF_TX_CB(skb)->copy_pending_idx[i])
++#define copy_count(skb) (XENVIF_TX_CB(skb)->copy_count)
+
+ static inline void xenvif_tx_create_map_op(struct xenvif_queue *queue,
+ u16 pending_idx,
+@@ -368,31 +371,93 @@ static inline struct sk_buff *xenvif_alloc_skb(unsigned int size)
+ return skb;
+ }
+
+-static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *queue,
+- struct sk_buff *skb,
+- struct xen_netif_tx_request *txp,
+- struct gnttab_map_grant_ref *gop,
+- unsigned int frag_overflow,
+- struct sk_buff *nskb)
++static void xenvif_get_requests(struct xenvif_queue *queue,
++ struct sk_buff *skb,
++ struct xen_netif_tx_request *first,
++ struct xen_netif_tx_request *txfrags,
++ unsigned *copy_ops,
++ unsigned *map_ops,
++ unsigned int frag_overflow,
++ struct sk_buff *nskb,
++ unsigned int extra_count,
++ unsigned int data_len)
+ {
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ skb_frag_t *frags = shinfo->frags;
+- u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
+- int start;
++ u16 pending_idx;
+ pending_ring_idx_t index;
+ unsigned int nr_slots;
++ struct gnttab_copy *cop = queue->tx_copy_ops + *copy_ops;
++ struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops;
++ struct xen_netif_tx_request *txp = first;
++
++ nr_slots = shinfo->nr_frags + 1;
++
++ copy_count(skb) = 0;
++
++ /* Create copy ops for exactly data_len bytes into the skb head. */
++ __skb_put(skb, data_len);
++ while (data_len > 0) {
++ int amount = data_len > txp->size ? txp->size : data_len;
++
++ cop->source.u.ref = txp->gref;
++ cop->source.domid = queue->vif->domid;
++ cop->source.offset = txp->offset;
++
++ cop->dest.domid = DOMID_SELF;
++ cop->dest.offset = (offset_in_page(skb->data +
++ skb_headlen(skb) -
++ data_len)) & ~XEN_PAGE_MASK;
++ cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb)
++ - data_len);
++
++ cop->len = amount;
++ cop->flags = GNTCOPY_source_gref;
+
+- nr_slots = shinfo->nr_frags;
++ index = pending_index(queue->pending_cons);
++ pending_idx = queue->pending_ring[index];
++ callback_param(queue, pending_idx).ctx = NULL;
++ copy_pending_idx(skb, copy_count(skb)) = pending_idx;
++ copy_count(skb)++;
++
++ cop++;
++ data_len -= amount;
+
+- /* Skip first skb fragment if it is on same page as header fragment. */
+- start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx);
++ if (amount == txp->size) {
++ /* The copy op covered the full tx_request */
++
++ memcpy(&queue->pending_tx_info[pending_idx].req,
++ txp, sizeof(*txp));
++ queue->pending_tx_info[pending_idx].extra_count =
++ (txp == first) ? extra_count : 0;
++
++ if (txp == first)
++ txp = txfrags;
++ else
++ txp++;
++ queue->pending_cons++;
++ nr_slots--;
++ } else {
++ /* The copy op partially covered the tx_request.
++ * The remainder will be mapped.
++ */
++ txp->offset += amount;
++ txp->size -= amount;
++ }
++ }
+
+- for (shinfo->nr_frags = start; shinfo->nr_frags < nr_slots;
+- shinfo->nr_frags++, txp++, gop++) {
++ for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
++ shinfo->nr_frags++, gop++) {
+ index = pending_index(queue->pending_cons++);
+ pending_idx = queue->pending_ring[index];
+- xenvif_tx_create_map_op(queue, pending_idx, txp, 0, gop);
++ xenvif_tx_create_map_op(queue, pending_idx, txp,
++ txp == first ? extra_count : 0, gop);
+ frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx);
++
++ if (txp == first)
++ txp = txfrags;
++ else
++ txp++;
+ }
+
+ if (frag_overflow) {
+@@ -413,7 +478,8 @@ static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *que
+ skb_shinfo(skb)->frag_list = nskb;
+ }
+
+- return gop;
++ (*copy_ops) = cop - queue->tx_copy_ops;
++ (*map_ops) = gop - queue->tx_map_ops;
+ }
+
+ static inline void xenvif_grant_handle_set(struct xenvif_queue *queue,
+@@ -449,7 +515,7 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
+ struct gnttab_copy **gopp_copy)
+ {
+ struct gnttab_map_grant_ref *gop_map = *gopp_map;
+- u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
++ u16 pending_idx;
+ /* This always points to the shinfo of the skb being checked, which
+ * could be either the first or the one on the frag_list
+ */
+@@ -460,24 +526,37 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
+ struct skb_shared_info *first_shinfo = NULL;
+ int nr_frags = shinfo->nr_frags;
+ const bool sharedslot = nr_frags &&
+- frag_get_pending_idx(&shinfo->frags[0]) == pending_idx;
++ frag_get_pending_idx(&shinfo->frags[0]) ==
++ copy_pending_idx(skb, copy_count(skb) - 1);
+ int i, err;
+
+- /* Check status of header. */
+- err = (*gopp_copy)->status;
+- if (unlikely(err)) {
+- if (net_ratelimit())
+- netdev_dbg(queue->vif->dev,
+- "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
+- (*gopp_copy)->status,
+- pending_idx,
+- (*gopp_copy)->source.u.ref);
+- /* The first frag might still have this slot mapped */
+- if (!sharedslot)
+- xenvif_idx_release(queue, pending_idx,
+- XEN_NETIF_RSP_ERROR);
++ for (i = 0; i < copy_count(skb); i++) {
++ int newerr;
++
++ /* Check status of header. */
++ pending_idx = copy_pending_idx(skb, i);
++
++ newerr = (*gopp_copy)->status;
++ if (likely(!newerr)) {
++ /* The first frag might still have this slot mapped */
++ if (i < copy_count(skb) - 1 || !sharedslot)
++ xenvif_idx_release(queue, pending_idx,
++ XEN_NETIF_RSP_OKAY);
++ } else {
++ err = newerr;
++ if (net_ratelimit())
++ netdev_dbg(queue->vif->dev,
++ "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
++ (*gopp_copy)->status,
++ pending_idx,
++ (*gopp_copy)->source.u.ref);
++ /* The first frag might still have this slot mapped */
++ if (i < copy_count(skb) - 1 || !sharedslot)
++ xenvif_idx_release(queue, pending_idx,
++ XEN_NETIF_RSP_ERROR);
++ }
++ (*gopp_copy)++;
+ }
+- (*gopp_copy)++;
+
+ check_frags:
+ for (i = 0; i < nr_frags; i++, gop_map++) {
+@@ -524,14 +603,6 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
+ if (err)
+ continue;
+
+- /* First error: if the header haven't shared a slot with the
+- * first frag, release it as well.
+- */
+- if (!sharedslot)
+- xenvif_idx_release(queue,
+- XENVIF_TX_CB(skb)->pending_idx,
+- XEN_NETIF_RSP_OKAY);
+-
+ /* Invalidate preceding fragments of this skb. */
+ for (j = 0; j < i; j++) {
+ pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
+@@ -801,7 +872,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ unsigned *copy_ops,
+ unsigned *map_ops)
+ {
+- struct gnttab_map_grant_ref *gop = queue->tx_map_ops;
+ struct sk_buff *skb, *nskb;
+ int ret;
+ unsigned int frag_overflow;
+@@ -883,8 +953,12 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ continue;
+ }
+
++ data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN) ?
++ XEN_NETBACK_TX_COPY_LEN : txreq.size;
++
+ ret = xenvif_count_requests(queue, &txreq, extra_count,
+ txfrags, work_to_do);
++
+ if (unlikely(ret < 0))
+ break;
+
+@@ -910,9 +984,8 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ index = pending_index(queue->pending_cons);
+ pending_idx = queue->pending_ring[index];
+
+- data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN &&
+- ret < XEN_NETBK_LEGACY_SLOTS_MAX) ?
+- XEN_NETBACK_TX_COPY_LEN : txreq.size;
++ if (ret >= XEN_NETBK_LEGACY_SLOTS_MAX - 1 && data_len < txreq.size)
++ data_len = txreq.size;
+
+ skb = xenvif_alloc_skb(data_len);
+ if (unlikely(skb == NULL)) {
+@@ -923,8 +996,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ }
+
+ skb_shinfo(skb)->nr_frags = ret;
+- if (data_len < txreq.size)
+- skb_shinfo(skb)->nr_frags++;
+ /* At this point shinfo->nr_frags is in fact the number of
+ * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX.
+ */
+@@ -986,54 +1057,19 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ type);
+ }
+
+- XENVIF_TX_CB(skb)->pending_idx = pending_idx;
+-
+- __skb_put(skb, data_len);
+- queue->tx_copy_ops[*copy_ops].source.u.ref = txreq.gref;
+- queue->tx_copy_ops[*copy_ops].source.domid = queue->vif->domid;
+- queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset;
+-
+- queue->tx_copy_ops[*copy_ops].dest.u.gmfn =
+- virt_to_gfn(skb->data);
+- queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
+- queue->tx_copy_ops[*copy_ops].dest.offset =
+- offset_in_page(skb->data) & ~XEN_PAGE_MASK;
+-
+- queue->tx_copy_ops[*copy_ops].len = data_len;
+- queue->tx_copy_ops[*copy_ops].flags = GNTCOPY_source_gref;
+-
+- (*copy_ops)++;
+-
+- if (data_len < txreq.size) {
+- frag_set_pending_idx(&skb_shinfo(skb)->frags[0],
+- pending_idx);
+- xenvif_tx_create_map_op(queue, pending_idx, &txreq,
+- extra_count, gop);
+- gop++;
+- } else {
+- frag_set_pending_idx(&skb_shinfo(skb)->frags[0],
+- INVALID_PENDING_IDX);
+- memcpy(&queue->pending_tx_info[pending_idx].req,
+- &txreq, sizeof(txreq));
+- queue->pending_tx_info[pending_idx].extra_count =
+- extra_count;
+- }
+-
+- queue->pending_cons++;
+-
+- gop = xenvif_get_requests(queue, skb, txfrags, gop,
+- frag_overflow, nskb);
++ xenvif_get_requests(queue, skb, &txreq, txfrags, copy_ops,
++ map_ops, frag_overflow, nskb, extra_count,
++ data_len);
+
+ __skb_queue_tail(&queue->tx_queue, skb);
+
+ queue->tx.req_cons = idx;
+
+- if (((gop-queue->tx_map_ops) >= ARRAY_SIZE(queue->tx_map_ops)) ||
++ if ((*map_ops >= ARRAY_SIZE(queue->tx_map_ops)) ||
+ (*copy_ops >= ARRAY_SIZE(queue->tx_copy_ops)))
+ break;
+ }
+
+- (*map_ops) = gop - queue->tx_map_ops;
+ return;
+ }
+
+@@ -1112,9 +1148,8 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
+ while ((skb = __skb_dequeue(&queue->tx_queue)) != NULL) {
+ struct xen_netif_tx_request *txp;
+ u16 pending_idx;
+- unsigned data_len;
+
+- pending_idx = XENVIF_TX_CB(skb)->pending_idx;
++ pending_idx = copy_pending_idx(skb, 0);
+ txp = &queue->pending_tx_info[pending_idx].req;
+
+ /* Check the remap error code. */
+@@ -1133,18 +1168,6 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
+ continue;
+ }
+
+- data_len = skb->len;
+- callback_param(queue, pending_idx).ctx = NULL;
+- if (data_len < txp->size) {
+- /* Append the packet payload as a fragment. */
+- txp->offset += data_len;
+- txp->size -= data_len;
+- } else {
+- /* Schedule a response immediately. */
+- xenvif_idx_release(queue, pending_idx,
+- XEN_NETIF_RSP_OKAY);
+- }
+-
+ if (txp->flags & XEN_NETTXF_csum_blank)
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ else if (txp->flags & XEN_NETTXF_data_validated)
+@@ -1331,7 +1354,7 @@ static inline void xenvif_tx_dealloc_action(struct xenvif_queue *queue)
+ /* Called after netfront has transmitted */
+ int xenvif_tx_action(struct xenvif_queue *queue, int budget)
+ {
+- unsigned nr_mops, nr_cops = 0;
++ unsigned nr_mops = 0, nr_cops = 0;
+ int work_done, ret;
+
+ if (unlikely(!tx_work_todo(queue)))
+--
+2.35.1
+