summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2024-12-09 06:35:46 -0500
committerMike Pagano <mpagano@gentoo.org>2024-12-09 06:35:46 -0500
commit663c931bba59f5d8c6e33ef0afc3857b3a1ac20d (patch)
treedb518d3b9fee31e29f1a12b2416faa5dd31ffef5
parentFix case for X86_USER_SHADOW_STACK (diff)
downloadlinux-patches-663c931bba59f5d8c6e33ef0afc3857b3a1ac20d.tar.gz
linux-patches-663c931bba59f5d8c6e33ef0afc3857b3a1ac20d.tar.bz2
linux-patches-663c931bba59f5d8c6e33ef0afc3857b3a1ac20d.zip
Linux patch 6.6.646.6-72
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1063_linux-6.6.64.patch28468
2 files changed, 28472 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 5c5a182f..9fb77406 100644
--- a/0000_README
+++ b/0000_README
@@ -295,6 +295,10 @@ Patch: 1062_linux-6.6.63.patch
From: https://www.kernel.org
Desc: Linux 6.6.63
+Patch: 1063_linux-6.6.64.patch
+From: https://www.kernel.org
+Desc: Linux 6.6.64
+
Patch: 1510_fs-enable-link-security-restrictions-by-default.patch
From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch
Desc: Enable link security restrictions by default.
diff --git a/1063_linux-6.6.64.patch b/1063_linux-6.6.64.patch
new file mode 100644
index 00000000..07895c1b
--- /dev/null
+++ b/1063_linux-6.6.64.patch
@@ -0,0 +1,28468 @@
+diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
+index 36c3cb5479013a..33675e718a3766 100644
+--- a/Documentation/ABI/testing/sysfs-fs-f2fs
++++ b/Documentation/ABI/testing/sysfs-fs-f2fs
+@@ -311,10 +311,13 @@ Description: Do background GC aggressively when set. Set to 0 by default.
+ GC approach and turns SSR mode on.
+ gc urgent low(2): lowers the bar of checking I/O idling in
+ order to process outstanding discard commands and GC a
+- little bit aggressively. uses cost benefit GC approach.
++ little bit aggressively. always uses cost benefit GC approach,
++ and will override age-threshold GC approach if ATGC is enabled
++ at the same time.
+ gc urgent mid(3): does GC forcibly in a period of given
+ gc_urgent_sleep_time and executes a mid level of I/O idling check.
+- uses cost benefit GC approach.
++ always uses cost benefit GC approach, and will override
++ age-threshold GC approach if ATGC is enabled at the same time.
+
+ What: /sys/fs/f2fs/<disk>/gc_urgent_sleep_time
+ Date: August 2017
+diff --git a/Documentation/RCU/stallwarn.rst b/Documentation/RCU/stallwarn.rst
+index ca7b7cd806a16c..30080ff6f4062d 100644
+--- a/Documentation/RCU/stallwarn.rst
++++ b/Documentation/RCU/stallwarn.rst
+@@ -249,7 +249,7 @@ ticks this GP)" indicates that this CPU has not taken any scheduling-clock
+ interrupts during the current stalled grace period.
+
+ The "idle=" portion of the message prints the dyntick-idle state.
+-The hex number before the first "/" is the low-order 12 bits of the
++The hex number before the first "/" is the low-order 16 bits of the
+ dynticks counter, which will have an even-numbered value if the CPU
+ is in dyntick-idle mode and an odd-numbered value otherwise. The hex
+ number between the two "/"s is the value of the nesting, which will be
+diff --git a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+index 5e942bccf27787..2b2041818a0a44 100644
+--- a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
++++ b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+@@ -26,9 +26,21 @@ properties:
+ description:
+ Specifies the reference clock(s) from which the output frequency is
+ derived. This must either reference one clock if only the first clock
+- input is connected or two if both clock inputs are connected.
+- minItems: 1
+- maxItems: 2
++ input is connected or two if both clock inputs are connected. The last
++ clock is the AXI bus clock that needs to be enabled so we can access the
++ core registers.
++ minItems: 2
++ maxItems: 3
++
++ clock-names:
++ oneOf:
++ - items:
++ - const: clkin1
++ - const: s_axi_aclk
++ - items:
++ - const: clkin1
++ - const: clkin2
++ - const: s_axi_aclk
+
+ '#clock-cells':
+ const: 0
+@@ -40,6 +52,7 @@ required:
+ - compatible
+ - reg
+ - clocks
++ - clock-names
+ - '#clock-cells'
+
+ additionalProperties: false
+@@ -50,5 +63,6 @@ examples:
+ compatible = "adi,axi-clkgen-2.00.a";
+ #clock-cells = <0>;
+ reg = <0xff000000 0x1000>;
+- clocks = <&osc 1>;
++ clocks = <&osc 1>, <&clkc 15>;
++ clock-names = "clkin1", "s_axi_aclk";
+ };
+diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
+index 96340a05754ce6..2beed2e2406c4e 100644
+--- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
++++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
+@@ -26,7 +26,7 @@ properties:
+ maxItems: 1
+
+ spi-max-frequency:
+- maximum: 30000000
++ maximum: 66000000
+
+ reset-gpios:
+ maxItems: 1
+diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml
+index 9418fd66a8e95a..b93254ad2a287a 100644
+--- a/Documentation/devicetree/bindings/serial/rs485.yaml
++++ b/Documentation/devicetree/bindings/serial/rs485.yaml
+@@ -18,16 +18,15 @@ properties:
+ description: prop-encoded-array <a b>
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ items:
+- items:
+- - description: Delay between rts signal and beginning of data sent in
+- milliseconds. It corresponds to the delay before sending data.
+- default: 0
+- maximum: 100
+- - description: Delay between end of data sent and rts signal in milliseconds.
+- It corresponds to the delay after sending data and actual release
+- of the line.
+- default: 0
+- maximum: 100
++ - description: Delay between rts signal and beginning of data sent in
++ milliseconds. It corresponds to the delay before sending data.
++ default: 0
++ maximum: 100
++ - description: Delay between end of data sent and rts signal in milliseconds.
++ It corresponds to the delay after sending data and actual release
++ of the line.
++ default: 0
++ maximum: 100
+
+ rs485-rts-active-high:
+ description: drive RTS high when sending (this is the default).
+diff --git a/Documentation/devicetree/bindings/sound/mt6359.yaml b/Documentation/devicetree/bindings/sound/mt6359.yaml
+index 23d411fc4200e6..128698630c865f 100644
+--- a/Documentation/devicetree/bindings/sound/mt6359.yaml
++++ b/Documentation/devicetree/bindings/sound/mt6359.yaml
+@@ -23,8 +23,8 @@ properties:
+ Indicates how many data pins are used to transmit two channels of PDM
+ signal. 0 means two wires, 1 means one wire. Default value is 0.
+ enum:
+- - 0 # one wire
+- - 1 # two wires
++ - 0 # two wires
++ - 1 # one wire
+
+ mediatek,mic-type-0:
+ $ref: /schemas/types.yaml#/definitions/uint32
+@@ -53,9 +53,9 @@ additionalProperties: false
+
+ examples:
+ - |
+- mt6359codec: mt6359codec {
+- mediatek,dmic-mode = <0>;
+- mediatek,mic-type-0 = <2>;
++ mt6359codec: audio-codec {
++ mediatek,dmic-mode = <0>;
++ mediatek,mic-type-0 = <2>;
+ };
+
+ ...
+diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+index 573578db950910..12a16031d7b6d0 100644
+--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+@@ -923,6 +923,8 @@ patternProperties:
+ description: National Semiconductor
+ "^nec,.*":
+ description: NEC LCD Technologies, Ltd.
++ "^neofidelity,.*":
++ description: Neofidelity Inc.
+ "^neonode,.*":
+ description: Neonode Inc.
+ "^netgear,.*":
+diff --git a/Documentation/filesystems/mount_api.rst b/Documentation/filesystems/mount_api.rst
+index 9aaf6ef75eb53b..0c69aa574ab9af 100644
+--- a/Documentation/filesystems/mount_api.rst
++++ b/Documentation/filesystems/mount_api.rst
+@@ -766,7 +766,8 @@ process the parameters it is given.
+
+ * ::
+
+- bool fs_validate_description(const struct fs_parameter_description *desc);
++ bool fs_validate_description(const char *name,
++ const struct fs_parameter_description *desc);
+
+ This performs some validation checks on a parameter description. It
+ returns true if the description is good and false if it is not. It will
+diff --git a/Documentation/locking/seqlock.rst b/Documentation/locking/seqlock.rst
+index bfda1a5fecadc6..ec6411d02ac8f5 100644
+--- a/Documentation/locking/seqlock.rst
++++ b/Documentation/locking/seqlock.rst
+@@ -153,7 +153,7 @@ Use seqcount_latch_t when the write side sections cannot be protected
+ from interruption by readers. This is typically the case when the read
+ side can be invoked from NMI handlers.
+
+-Check `raw_write_seqcount_latch()` for more information.
++Check `write_seqcount_latch()` for more information.
+
+
+ .. _seqlock_t:
+diff --git a/Documentation/networking/j1939.rst b/Documentation/networking/j1939.rst
+index e4bd7aa1f5aa9d..544bad175aae2d 100644
+--- a/Documentation/networking/j1939.rst
++++ b/Documentation/networking/j1939.rst
+@@ -121,7 +121,7 @@ format, the Group Extension is set in the PS-field.
+
+ On the other hand, when using PDU1 format, the PS-field contains a so-called
+ Destination Address, which is _not_ part of the PGN. When communicating a PGN
+-from user space to kernel (or vice versa) and PDU2 format is used, the PS-field
++from user space to kernel (or vice versa) and PDU1 format is used, the PS-field
+ of the PGN shall be set to zero. The Destination Address shall be set
+ elsewhere.
+
+diff --git a/Makefile b/Makefile
+index 611d7de2e3a22a..74f3867461a0ec 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 6
+-SUBLEVEL = 63
++SUBLEVEL = 64
+ EXTRAVERSION =
+ NAME = Pinguïn Aangedreven
+
+diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c
+index 4c9e61457b2f69..cc6ac7d128aa1a 100644
+--- a/arch/arc/kernel/devtree.c
++++ b/arch/arc/kernel/devtree.c
+@@ -62,7 +62,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt)
+ const struct machine_desc *mdesc;
+ unsigned long dt_root;
+
+- if (!early_init_dt_scan(dt))
++ if (!early_init_dt_scan(dt, __pa(dt)))
+ return NULL;
+
+ mdesc = of_flat_dt_match_machine(NULL, arch_get_next_mach);
+diff --git a/arch/arm/boot/dts/allwinner/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/allwinner/sun9i-a80-cubieboard4.dts
+index c8ca8cb7f5c94e..52ad95a2063aaf 100644
+--- a/arch/arm/boot/dts/allwinner/sun9i-a80-cubieboard4.dts
++++ b/arch/arm/boot/dts/allwinner/sun9i-a80-cubieboard4.dts
+@@ -280,8 +280,8 @@ reg_dcdc4: dcdc4 {
+
+ reg_dcdc5: dcdc5 {
+ regulator-always-on;
+- regulator-min-microvolt = <1425000>;
+- regulator-max-microvolt = <1575000>;
++ regulator-min-microvolt = <1450000>;
++ regulator-max-microvolt = <1550000>;
+ regulator-name = "vcc-dram";
+ };
+
+diff --git a/arch/arm/boot/dts/microchip/sam9x60.dtsi b/arch/arm/boot/dts/microchip/sam9x60.dtsi
+index 1705c96f4221e8..ae089d4bd660ed 100644
+--- a/arch/arm/boot/dts/microchip/sam9x60.dtsi
++++ b/arch/arm/boot/dts/microchip/sam9x60.dtsi
+@@ -186,6 +186,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 13>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -384,6 +385,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 32>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -433,6 +435,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 33>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -590,6 +593,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 9>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -639,6 +643,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -688,6 +693,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 11>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -737,6 +743,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -805,6 +812,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 6>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -873,6 +881,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 7>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -941,6 +950,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 8>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -1064,6 +1074,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 15>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+@@ -1113,6 +1124,7 @@ AT91_XDMAC_DT_PER_IF(1) |
+ dma-names = "tx", "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 16>;
+ clock-names = "usart";
++ atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ atmel,fifo-size = <16>;
+diff --git a/arch/arm/boot/dts/ti/omap/omap36xx.dtsi b/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
+index e6d8070c1bf88d..cba8ba51657bb7 100644
+--- a/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
++++ b/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
+@@ -72,6 +72,7 @@ opp-1000000000 {
+ <1375000 1375000 1375000>;
+ /* only on am/dm37x with speed-binned bit set */
+ opp-supported-hw = <0xffffffff 2>;
++ turbo-mode;
+ };
+ };
+
+diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
+index 264827281113b0..abf13b21ba76fd 100644
+--- a/arch/arm/kernel/devtree.c
++++ b/arch/arm/kernel/devtree.c
+@@ -201,7 +201,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt_virt)
+
+ mdesc_best = &__mach_desc_GENERIC_DT;
+
+- if (!dt_virt || !early_init_dt_verify(dt_virt))
++ if (!dt_virt || !early_init_dt_verify(dt_virt, __pa(dt_virt)))
+ return NULL;
+
+ mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);
+diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
+index 6150a716828c3e..0384fbbdc28d83 100644
+--- a/arch/arm/kernel/entry-armv.S
++++ b/arch/arm/kernel/entry-armv.S
+@@ -25,6 +25,7 @@
+ #include <asm/tls.h>
+ #include <asm/system_info.h>
+ #include <asm/uaccess-asm.h>
++#include <asm/kasan_def.h>
+
+ #include "entry-header.S"
+ #include <asm/probes.h>
+@@ -555,6 +556,13 @@ ENTRY(__switch_to)
+ @ entries covering the vmalloc region.
+ @
+ ldr r2, [ip]
++#ifdef CONFIG_KASAN_VMALLOC
++ @ Also dummy read from the KASAN shadow memory for the new stack if we
++ @ are using KASAN
++ mov_l r2, KASAN_SHADOW_OFFSET
++ add r2, r2, ip, lsr #KASAN_SHADOW_SCALE_SHIFT
++ ldr r2, [r2]
++#endif
+ #endif
+
+ @ When CONFIG_THREAD_INFO_IN_TASK=n, the update of SP itself is what
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 28873cda464f51..f22c50d4bd4173 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -411,7 +411,11 @@ ENTRY(secondary_startup)
+ /*
+ * Use the page tables supplied from __cpu_up.
+ */
++#ifdef CONFIG_XIP_KERNEL
++ ldr r3, =(secondary_data + PLAT_PHYS_OFFSET - PAGE_OFFSET)
++#else
+ adr_l r3, secondary_data
++#endif
+ mov_l r12, __secondary_switched
+ ldrd r4, r5, [r3, #0] @ get secondary_data.pgdir
+ ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE:
+diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c
+index d4392e1774848d..3bb0c4dcfc5c95 100644
+--- a/arch/arm/kernel/psci_smp.c
++++ b/arch/arm/kernel/psci_smp.c
+@@ -45,8 +45,15 @@ extern void secondary_startup(void);
+ static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
+ {
+ if (psci_ops.cpu_on)
++#ifdef CONFIG_XIP_KERNEL
++ return psci_ops.cpu_on(cpu_logical_map(cpu),
++ ((phys_addr_t)(&secondary_startup)
++ - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
++ + CONFIG_XIP_PHYS_ADDR));
++#else
+ return psci_ops.cpu_on(cpu_logical_map(cpu),
+ virt_to_idmap(&secondary_startup));
++#endif
+ return -ENODEV;
+ }
+
+diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
+index 448e57c6f65344..4a833e89782aa2 100644
+--- a/arch/arm/mm/idmap.c
++++ b/arch/arm/mm/idmap.c
+@@ -84,8 +84,15 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
+ unsigned long addr, end;
+ unsigned long next;
+
++#ifdef CONFIG_XIP_KERNEL
++ addr = (phys_addr_t)(text_start) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
++ + CONFIG_XIP_PHYS_ADDR;
++ end = (phys_addr_t)(text_end) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
++ + CONFIG_XIP_PHYS_ADDR;
++#else
+ addr = virt_to_idmap(text_start);
+ end = virt_to_idmap(text_end);
++#endif
+ pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);
+
+ prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
+diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
+index 2129070065c323..1c5aeba9bc27f3 100644
+--- a/arch/arm/mm/ioremap.c
++++ b/arch/arm/mm/ioremap.c
+@@ -23,6 +23,7 @@
+ */
+ #include <linux/module.h>
+ #include <linux/errno.h>
++#include <linux/kasan.h>
+ #include <linux/mm.h>
+ #include <linux/vmalloc.h>
+ #include <linux/io.h>
+@@ -115,16 +116,40 @@ int ioremap_page(unsigned long virt, unsigned long phys,
+ }
+ EXPORT_SYMBOL(ioremap_page);
+
++#ifdef CONFIG_KASAN
++static unsigned long arm_kasan_mem_to_shadow(unsigned long addr)
++{
++ return (unsigned long)kasan_mem_to_shadow((void *)addr);
++}
++#else
++static unsigned long arm_kasan_mem_to_shadow(unsigned long addr)
++{
++ return 0;
++}
++#endif
++
++static void memcpy_pgd(struct mm_struct *mm, unsigned long start,
++ unsigned long end)
++{
++ end = ALIGN(end, PGDIR_SIZE);
++ memcpy(pgd_offset(mm, start), pgd_offset_k(start),
++ sizeof(pgd_t) * (pgd_index(end) - pgd_index(start)));
++}
++
+ void __check_vmalloc_seq(struct mm_struct *mm)
+ {
+ int seq;
+
+ do {
+- seq = atomic_read(&init_mm.context.vmalloc_seq);
+- memcpy(pgd_offset(mm, VMALLOC_START),
+- pgd_offset_k(VMALLOC_START),
+- sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
+- pgd_index(VMALLOC_START)));
++ seq = atomic_read_acquire(&init_mm.context.vmalloc_seq);
++ memcpy_pgd(mm, VMALLOC_START, VMALLOC_END);
++ if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
++ unsigned long start =
++ arm_kasan_mem_to_shadow(VMALLOC_START);
++ unsigned long end =
++ arm_kasan_mem_to_shadow(VMALLOC_END);
++ memcpy_pgd(mm, start, end);
++ }
+ /*
+ * Use a store-release so that other CPUs that observe the
+ * counter's new value are guaranteed to see the results of the
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+index 87847116ab6d9b..b0885a38995102 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+@@ -202,6 +202,9 @@ accelerometer@68 {
+ interrupts = <7 5 IRQ_TYPE_EDGE_RISING>; /* PH5 */
+ vdd-supply = <&reg_dldo1>;
+ vddio-supply = <&reg_dldo1>;
++ mount-matrix = "0", "1", "0",
++ "-1", "0", "0",
++ "0", "0", "1";
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
+index 14d20a33af8e15..6c48fa4b0d0c4f 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
+@@ -145,7 +145,7 @@ reg_usdhc2_vmmc: regulator-usdhc2 {
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_SD";
+- startup-delay-us = <2000>;
++ startup-delay-us = <20000>;
+ };
+
+ reserved-memory {
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+index e9e4fcb562f10c..b9902adbfe6248 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+@@ -134,7 +134,7 @@ reg_usdhc2_vmmc: regulator-usdhc2 {
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_SD";
+- startup-delay-us = <2000>;
++ startup-delay-us = <20000>;
+ };
+
+ reserved-memory {
+diff --git a/arch/arm64/boot/dts/mediatek/mt6357.dtsi b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
+index 3330a03c2f7453..5fafa842d312f3 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6357.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
+@@ -10,6 +10,11 @@ &pwrap {
+ mt6357_pmic: pmic {
+ compatible = "mediatek,mt6357";
+
++ pmic_adc: adc {
++ compatible = "mediatek,mt6357-auxadc";
++ #io-channel-cells = <1>;
++ };
++
+ regulators {
+ mt6357_vproc_reg: buck-vproc {
+ regulator-name = "vproc";
+diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+index b605313bed99d1..9a549069a483ea 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+@@ -12,12 +12,17 @@ pmic: pmic {
+ interrupts = <182 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+
+- mt6358codec: mt6358codec {
++ pmic_adc: adc {
++ compatible = "mediatek,mt6358-auxadc";
++ #io-channel-cells = <1>;
++ };
++
++ mt6358codec: audio-codec {
+ compatible = "mediatek,mt6358-sound";
+ mediatek,dmic-mode = <0>; /* two-wires */
+ };
+
+- mt6358regulator: mt6358regulator {
++ mt6358regulator: regulators {
+ compatible = "mediatek,mt6358-regulator";
+
+ mt6358_vdram1_reg: buck_vdram1 {
+diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+index df3e822232d340..8e1b8c85c6ede9 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+@@ -9,6 +9,11 @@ pmic: pmic {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
++ pmic_adc: adc {
++ compatible = "mediatek,mt6359-auxadc";
++ #io-channel-cells = <1>;
++ };
++
+ mt6359codec: mt6359codec {
+ };
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+index bdcd35cecad908..fd6230352f4fd1 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+@@ -43,6 +43,14 @@ trackpad2: trackpad@2c {
+ interrupts = <117 IRQ_TYPE_LEVEL_LOW>;
+ reg = <0x2c>;
+ hid-descr-addr = <0x0020>;
++ /*
++ * The trackpad needs a post-power-on delay of 100ms,
++ * but at time of writing, the power supply for it on
++ * this board is always on. The delay is therefore not
++ * added to avoid impacting the readiness of the
++ * trackpad.
++ */
++ vdd-supply = <&mt6397_vgp6_reg>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
+index 19c1e2bee494c9..20b71f2e7159ad 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
+@@ -30,3 +30,6 @@ touchscreen@2c {
+ };
+ };
+
++&i2c2 {
++ i2c-scl-internal-delay-ns = <4100>;
++};
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
+index 072133fb0f0162..47905f84bc1613 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
+@@ -17,6 +17,8 @@ &i2c_tunnel {
+ };
+
+ &i2c2 {
++ i2c-scl-internal-delay-ns = <25000>;
++
+ trackpad@2c {
+ compatible = "hid-over-i2c";
+ reg = <0x2c>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
+index 552bfc72699945..9a166dccd727c7 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
+@@ -31,3 +31,6 @@ &qca_wifi {
+ qcom,ath10k-calibration-variant = "GO_DAMU";
+ };
+
++&i2c2 {
++ i2c-scl-internal-delay-ns = <20000>;
++};
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
+index bbe6c338f465ee..f9c1ec366b2660 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
+@@ -25,3 +25,6 @@ trackpad@2c {
+ };
+ };
+
++&i2c2 {
++ i2c-scl-internal-delay-ns = <21500>;
++};
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
+index 32f6899f885ef7..629c4b7ecbc629 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
+@@ -8,28 +8,32 @@
+ #include <arm/cros-ec-keyboard.dtsi>
+
+ / {
+- pp1200_mipibrdg: pp1200-mipibrdg {
++ pp1000_mipibrdg: pp1000-mipibrdg {
+ compatible = "regulator-fixed";
+- regulator-name = "pp1200_mipibrdg";
++ regulator-name = "pp1000_mipibrdg";
++ regulator-min-microvolt = <1000000>;
++ regulator-max-microvolt = <1000000>;
+ pinctrl-names = "default";
+- pinctrl-0 = <&pp1200_mipibrdg_en>;
++ pinctrl-0 = <&pp1000_mipibrdg_en>;
+
+ enable-active-high;
+ regulator-boot-on;
+
+ gpio = <&pio 54 GPIO_ACTIVE_HIGH>;
++ vin-supply = <&pp1800_alw>;
+ };
+
+ pp1800_mipibrdg: pp1800-mipibrdg {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_mipibrdg";
+ pinctrl-names = "default";
+- pinctrl-0 = <&pp1800_lcd_en>;
++ pinctrl-0 = <&pp1800_mipibrdg_en>;
+
+ enable-active-high;
+ regulator-boot-on;
+
+ gpio = <&pio 36 GPIO_ACTIVE_HIGH>;
++ vin-supply = <&pp1800_alw>;
+ };
+
+ pp3300_panel: pp3300-panel {
+@@ -44,18 +48,20 @@ pp3300_panel: pp3300-panel {
+ regulator-boot-on;
+
+ gpio = <&pio 35 GPIO_ACTIVE_HIGH>;
++ vin-supply = <&pp3300_alw>;
+ };
+
+- vddio_mipibrdg: vddio-mipibrdg {
++ pp3300_mipibrdg: pp3300-mipibrdg {
+ compatible = "regulator-fixed";
+- regulator-name = "vddio_mipibrdg";
++ regulator-name = "pp3300_mipibrdg";
+ pinctrl-names = "default";
+- pinctrl-0 = <&vddio_mipibrdg_en>;
++ pinctrl-0 = <&pp3300_mipibrdg_en>;
+
+ enable-active-high;
+ regulator-boot-on;
+
+ gpio = <&pio 37 GPIO_ACTIVE_HIGH>;
++ vin-supply = <&pp3300_alw>;
+ };
+
+ volume_buttons: volume-buttons {
+@@ -152,9 +158,9 @@ anx_bridge: anx7625@58 {
+ panel_flags = <1>;
+ enable-gpios = <&pio 45 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&pio 73 GPIO_ACTIVE_HIGH>;
+- vdd10-supply = <&pp1200_mipibrdg>;
++ vdd10-supply = <&pp1000_mipibrdg>;
+ vdd18-supply = <&pp1800_mipibrdg>;
+- vdd33-supply = <&vddio_mipibrdg>;
++ vdd33-supply = <&pp3300_mipibrdg>;
+
+ ports {
+ #address-cells = <1>;
+@@ -397,14 +403,14 @@ &pio {
+ "",
+ "";
+
+- pp1200_mipibrdg_en: pp1200-mipibrdg-en {
++ pp1000_mipibrdg_en: pp1000-mipibrdg-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO54__FUNC_GPIO54>;
+ output-low;
+ };
+ };
+
+- pp1800_lcd_en: pp1800-lcd-en {
++ pp1800_mipibrdg_en: pp1800-mipibrdg-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO36__FUNC_GPIO36>;
+ output-low;
+@@ -466,7 +472,7 @@ trackpad-int {
+ };
+ };
+
+- vddio_mipibrdg_en: vddio-mipibrdg-en {
++ pp3300_mipibrdg_en: pp3300-mipibrdg-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO37__FUNC_GPIO37>;
+ output-low;
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+index 0d3c7b8162ff0b..9eca1c80fe0107 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+@@ -105,9 +105,9 @@ &i2c4 {
+ clock-frequency = <400000>;
+ vbus-supply = <&mt6358_vcn18_reg>;
+
+- eeprom@54 {
++ eeprom@50 {
+ compatible = "atmel,24c32";
+- reg = <0x54>;
++ reg = <0x50>;
+ pagesize = <32>;
+ vcc-supply = <&mt6358_vcn18_reg>;
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+index e73113cb51f538..29216ebe4de845 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+@@ -80,9 +80,9 @@ &i2c4 {
+ clock-frequency = <400000>;
+ vbus-supply = <&mt6358_vcn18_reg>;
+
+- eeprom@54 {
++ eeprom@50 {
+ compatible = "atmel,24c64";
+- reg = <0x54>;
++ reg = <0x50>;
+ pagesize = <32>;
+ vcc-supply = <&mt6358_vcn18_reg>;
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+index 181da69d18f46a..b0469a95ddc430 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+@@ -89,9 +89,9 @@ &i2c4 {
+ clock-frequency = <400000>;
+ vbus-supply = <&mt6358_vcn18_reg>;
+
+- eeprom@54 {
++ eeprom@50 {
+ compatible = "atmel,24c32";
+- reg = <0x54>;
++ reg = <0x50>;
+ pagesize = <32>;
+ vcc-supply = <&mt6358_vcn18_reg>;
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+index 34e18eb5d7f450..b21663b46b5192 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+@@ -1296,6 +1296,7 @@ &xhci1 {
+
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ vbus-supply = <&usb_vbus>;
++ mediatek,u3p-dis-msk = <1>;
+ };
+
+ &xhci2 {
+@@ -1312,7 +1313,6 @@ &xhci3 {
+ usb2-lpm-disable;
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ vbus-supply = <&usb_vbus>;
+- mediatek,u3p-dis-msk = <1>;
+ };
+
+ #include <arm/cros-ec-keyboard.dtsi>
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+index d21ba00a5bd5df..5a087404ccc2d9 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+@@ -487,7 +487,7 @@ topckgen: syscon@10000000 {
+ };
+
+ infracfg_ao: syscon@10001000 {
+- compatible = "mediatek,mt8195-infracfg_ao", "syscon", "simple-mfd";
++ compatible = "mediatek,mt8195-infracfg_ao", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+@@ -2845,11 +2845,9 @@ &larb19 &larb21 &larb24 &larb25
+ mutex1: mutex@1c101000 {
+ compatible = "mediatek,mt8195-disp-mutex";
+ reg = <0 0x1c101000 0 0x1000>;
+- reg-names = "vdo1_mutex";
+ interrupts = <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH 0>;
+ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+ clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
+- clock-names = "vdo1_mutex";
+ mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x1000 0x1000>;
+ mediatek,gce-events = <CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0>;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
+index 92b85de7706d39..dfeeada91b7800 100644
+--- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
+@@ -3618,7 +3618,7 @@ lmh@18358800 {
+ };
+
+ cpufreq_hw: cpufreq@18323000 {
+- compatible = "qcom,cpufreq-hw";
++ compatible = "qcom,sc8180x-cpufreq-hw", "qcom,cpufreq-hw";
+ reg = <0 0x18323000 0 0x1400>, <0 0x18325800 0 0x1400>;
+ reg-names = "freq-domain0", "freq-domain1";
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+index 2efceb49a3218e..f271b69485c5ce 100644
+--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+@@ -1351,43 +1351,43 @@ gpu_opp_table: opp-table {
+ opp-850000000 {
+ opp-hz = /bits/ 64 <850000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+- opp-supported-hw = <0x02>;
++ opp-supported-hw = <0x03>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+- opp-supported-hw = <0x04>;
++ opp-supported-hw = <0x07>;
+ };
+
+ opp-650000000 {
+ opp-hz = /bits/ 64 <650000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+- opp-supported-hw = <0x08>;
++ opp-supported-hw = <0x0f>;
+ };
+
+ opp-565000000 {
+ opp-hz = /bits/ 64 <565000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+- opp-supported-hw = <0x10>;
++ opp-supported-hw = <0x1f>;
+ };
+
+ opp-430000000 {
+ opp-hz = /bits/ 64 <430000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+- opp-supported-hw = <0xff>;
++ opp-supported-hw = <0x1f>;
+ };
+
+ opp-355000000 {
+ opp-hz = /bits/ 64 <355000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+- opp-supported-hw = <0xff>;
++ opp-supported-hw = <0x1f>;
+ };
+
+ opp-253000000 {
+ opp-hz = /bits/ 64 <253000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+- opp-supported-hw = <0xff>;
++ opp-supported-hw = <0x1f>;
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi b/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi
+index 8e2db1d6ca81e2..25c55b32aafe5a 100644
+--- a/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi
++++ b/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi
+@@ -69,9 +69,6 @@ &rcar_sound {
+
+ status = "okay";
+
+- /* Single DAI */
+- #sound-dai-cells = <0>;
+-
+ rsnd_port: port {
+ rsnd_endpoint: endpoint {
+ remote-endpoint = <&dw_hdmi0_snd_in>;
+diff --git a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
+index 7fc0339a3ac978..e59191562d06c1 100644
+--- a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
++++ b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
+@@ -84,9 +84,6 @@ &rcar_sound {
+ pinctrl-names = "default";
+ status = "okay";
+
+- /* Single DAI */
+- #sound-dai-cells = <0>;
+-
+ /* audio_clkout0/1/2/3 */
+ #clock-cells = <1>;
+ clock-frequency = <12288000 11289600>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+index 9299fa7e3e2150..e813d426be1052 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+@@ -34,7 +34,7 @@ sdio_pwrseq: sdio-pwrseq {
+
+ sound {
+ compatible = "audio-graph-card";
+- label = "rockchip,es8388-codec";
++ label = "rockchip,es8388";
+ widgets = "Microphone", "Mic Jack",
+ "Headphone", "Headphones";
+ routing = "LINPUT2", "Mic Jack",
+diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+index 0a5634ca005dfb..e931c966b7f22b 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+@@ -134,7 +134,7 @@ reg_sdhc1_vmmc: regulator-sdhci1 {
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_SD";
+- startup-delay-us = <2000>;
++ startup-delay-us = <20000>;
+ };
+
+ reg_sdhc1_vqmmc: regulator-sdhci1-vqmmc {
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+index 7a0c599f2b1c35..9b122117ef72dd 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
++++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+@@ -192,7 +192,7 @@ J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */
+ };
+ };
+
+-&main_pmx1 {
++&main_pmx2 {
+ main_usbss0_pins_default: main-usbss0-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x04, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+index cdb1d6b2a98295..e5ff6f038a9aca 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+@@ -395,7 +395,7 @@ cpts@3d000 {
+
+ /* TIMERIO pad input CTRLMMR_TIMER*_CTRL registers */
+ main_timerio_input: pinctrl@104200 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ reg = <0x0 0x104200 0x0 0x50>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+@@ -404,7 +404,7 @@ main_timerio_input: pinctrl@104200 {
+
+ /* TIMERIO pad output CTCTRLMMR_TIMERIO*_CTRL registers */
+ main_timerio_output: pinctrl@104280 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ reg = <0x0 0x104280 0x0 0x20>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+@@ -412,7 +412,7 @@ main_timerio_output: pinctrl@104280 {
+ };
+
+ main_pmx0: pinctrl@11c000 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ /* Proxy 0 addressing */
+ reg = <0x00 0x11c000 0x00 0x10c>;
+ #pinctrl-cells = <1>;
+@@ -420,10 +420,28 @@ main_pmx0: pinctrl@11c000 {
+ pinctrl-single,function-mask = <0xffffffff>;
+ };
+
+- main_pmx1: pinctrl@11c11c {
+- compatible = "pinctrl-single";
++ main_pmx1: pinctrl@11c110 {
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ /* Proxy 0 addressing */
+- reg = <0x00 0x11c11c 0x00 0xc>;
++ reg = <0x00 0x11c110 0x00 0x004>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ main_pmx2: pinctrl@11c11c {
++ compatible = "ti,j7200-padconf", "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x11c11c 0x00 0x00c>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ main_pmx3: pinctrl@11c164 {
++ compatible = "ti,j7200-padconf", "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x11c164 0x00 0x008>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+@@ -897,7 +915,7 @@ main_spi0: spi@2100000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 266 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 266 1>;
++ clocks = <&k3_clks 266 4>;
+ status = "disabled";
+ };
+
+@@ -908,7 +926,7 @@ main_spi1: spi@2110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 267 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 267 1>;
++ clocks = <&k3_clks 267 4>;
+ status = "disabled";
+ };
+
+@@ -919,7 +937,7 @@ main_spi2: spi@2120000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 268 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 268 1>;
++ clocks = <&k3_clks 268 4>;
+ status = "disabled";
+ };
+
+@@ -930,7 +948,7 @@ main_spi3: spi@2130000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 269 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 269 1>;
++ clocks = <&k3_clks 269 4>;
+ status = "disabled";
+ };
+
+@@ -941,7 +959,7 @@ main_spi4: spi@2140000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 270 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 270 1>;
++ clocks = <&k3_clks 270 2>;
+ status = "disabled";
+ };
+
+@@ -952,7 +970,7 @@ main_spi5: spi@2150000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 271 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 271 1>;
++ clocks = <&k3_clks 271 4>;
+ status = "disabled";
+ };
+
+@@ -963,7 +981,7 @@ main_spi6: spi@2160000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 272 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 272 1>;
++ clocks = <&k3_clks 272 4>;
+ status = "disabled";
+ };
+
+@@ -974,7 +992,7 @@ main_spi7: spi@2170000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 273 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 273 1>;
++ clocks = <&k3_clks 273 4>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+index 6ffaf85fa63f50..8e9d0a25e23667 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+@@ -185,7 +185,7 @@ chipid@43000014 {
+
+ /* MCU_TIMERIO pad input CTRLMMR_MCU_TIMER*_CTRL registers */
+ mcu_timerio_input: pinctrl@40f04200 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ reg = <0x0 0x40f04200 0x0 0x28>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+@@ -195,7 +195,7 @@ mcu_timerio_input: pinctrl@40f04200 {
+
+ /* MCU_TIMERIO pad output CTRLMMR_MCU_TIMERIO*_CTRL registers */
+ mcu_timerio_output: pinctrl@40f04280 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ reg = <0x0 0x40f04280 0x0 0x28>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+@@ -204,7 +204,7 @@ mcu_timerio_output: pinctrl@40f04280 {
+ };
+
+ wkup_pmx0: pinctrl@4301c000 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ /* Proxy 0 addressing */
+ reg = <0x00 0x4301c000 0x00 0x34>;
+ #pinctrl-cells = <1>;
+@@ -213,7 +213,7 @@ wkup_pmx0: pinctrl@4301c000 {
+ };
+
+ wkup_pmx1: pinctrl@4301c038 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ /* Proxy 0 addressing */
+ reg = <0x00 0x4301c038 0x00 0x8>;
+ #pinctrl-cells = <1>;
+@@ -222,7 +222,7 @@ wkup_pmx1: pinctrl@4301c038 {
+ };
+
+ wkup_pmx2: pinctrl@4301c068 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ /* Proxy 0 addressing */
+ reg = <0x00 0x4301c068 0x00 0xec>;
+ #pinctrl-cells = <1>;
+@@ -231,7 +231,7 @@ wkup_pmx2: pinctrl@4301c068 {
+ };
+
+ wkup_pmx3: pinctrl@4301c174 {
+- compatible = "pinctrl-single";
++ compatible = "ti,j7200-padconf", "pinctrl-single";
+ /* Proxy 0 addressing */
+ reg = <0x00 0x4301c174 0x00 0x20>;
+ #pinctrl-cells = <1>;
+@@ -481,7 +481,7 @@ mcu_spi0: spi@40300000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 274 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 274 0>;
++ clocks = <&k3_clks 274 4>;
+ status = "disabled";
+ };
+
+@@ -492,7 +492,7 @@ mcu_spi1: spi@40310000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 275 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 275 0>;
++ clocks = <&k3_clks 275 4>;
+ status = "disabled";
+ };
+
+@@ -503,7 +503,7 @@ mcu_spi2: spi@40320000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 276 0>;
++ clocks = <&k3_clks 276 2>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+index 05d6ef127ba784..1893d611b17357 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+@@ -637,7 +637,7 @@ mcu_spi0: spi@40300000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 274 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 274 0>;
++ clocks = <&k3_clks 274 1>;
+ status = "disabled";
+ };
+
+@@ -648,7 +648,7 @@ mcu_spi1: spi@40310000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 275 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 275 0>;
++ clocks = <&k3_clks 275 1>;
+ status = "disabled";
+ };
+
+@@ -659,7 +659,7 @@ mcu_spi2: spi@40320000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 276 0>;
++ clocks = <&k3_clks 276 1>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+index 084f8f5b669931..9484347acba794 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+@@ -1569,7 +1569,7 @@ main_spi0: spi@2100000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 339 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 339 1>;
++ clocks = <&k3_clks 339 2>;
+ status = "disabled";
+ };
+
+@@ -1580,7 +1580,7 @@ main_spi1: spi@2110000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 340 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 340 1>;
++ clocks = <&k3_clks 340 2>;
+ status = "disabled";
+ };
+
+@@ -1591,7 +1591,7 @@ main_spi2: spi@2120000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 341 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 341 1>;
++ clocks = <&k3_clks 341 2>;
+ status = "disabled";
+ };
+
+@@ -1602,7 +1602,7 @@ main_spi3: spi@2130000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 342 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 342 1>;
++ clocks = <&k3_clks 342 2>;
+ status = "disabled";
+ };
+
+@@ -1613,7 +1613,7 @@ main_spi4: spi@2140000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 343 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 343 1>;
++ clocks = <&k3_clks 343 2>;
+ status = "disabled";
+ };
+
+@@ -1624,7 +1624,7 @@ main_spi5: spi@2150000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 344 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 344 1>;
++ clocks = <&k3_clks 344 2>;
+ status = "disabled";
+ };
+
+@@ -1635,7 +1635,7 @@ main_spi6: spi@2160000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 345 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 345 1>;
++ clocks = <&k3_clks 345 2>;
+ status = "disabled";
+ };
+
+@@ -1646,7 +1646,7 @@ main_spi7: spi@2170000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 346 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 346 1>;
++ clocks = <&k3_clks 346 2>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+index 71324fec415ae2..6fc008fbfb003f 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+@@ -416,7 +416,7 @@ mcu_spi0: spi@40300000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 347 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 347 0>;
++ clocks = <&k3_clks 347 2>;
+ status = "disabled";
+ };
+
+@@ -427,7 +427,7 @@ mcu_spi1: spi@40310000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 348 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 348 0>;
++ clocks = <&k3_clks 348 2>;
+ status = "disabled";
+ };
+
+@@ -438,7 +438,7 @@ mcu_spi2: spi@40320000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 349 TI_SCI_PD_EXCLUSIVE>;
+- clocks = <&k3_clks 349 0>;
++ clocks = <&k3_clks 349 2>;
+ status = "disabled";
+ };
+
+diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
+index db1aeacd4cd99d..0ccf51afde31a6 100644
+--- a/arch/arm64/include/asm/insn.h
++++ b/arch/arm64/include/asm/insn.h
+@@ -347,6 +347,7 @@ __AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
+ __AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000)
+ __AARCH64_INSN_FUNCS(load_ex, 0x3F400000, 0x08400000)
+ __AARCH64_INSN_FUNCS(store_ex, 0x3F400000, 0x08000000)
++__AARCH64_INSN_FUNCS(mops, 0x3B200C00, 0x19000400)
+ __AARCH64_INSN_FUNCS(stp, 0x7FC00000, 0x29000000)
+ __AARCH64_INSN_FUNCS(ldp, 0x7FC00000, 0x29400000)
+ __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000)
+diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
+index af06ccb7ee3433..b84ed3ad91a9eb 100644
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -72,8 +72,6 @@ enum kvm_mode kvm_get_mode(void);
+ static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
+ #endif
+
+-DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
+-
+ extern unsigned int __ro_after_init kvm_sve_max_vl;
+ int __init kvm_arm_init_sve(void);
+
+diff --git a/arch/arm64/kernel/probes/decode-insn.c b/arch/arm64/kernel/probes/decode-insn.c
+index 3496d6169e59b2..42b69936cee34b 100644
+--- a/arch/arm64/kernel/probes/decode-insn.c
++++ b/arch/arm64/kernel/probes/decode-insn.c
+@@ -58,10 +58,13 @@ static bool __kprobes aarch64_insn_is_steppable(u32 insn)
+ * Instructions which load PC relative literals are not going to work
+ * when executed from an XOL slot. Instructions doing an exclusive
+ * load/store are not going to complete successfully when single-step
+- * exception handling happens in the middle of the sequence.
++ * exception handling happens in the middle of the sequence. Memory
++ * copy/set instructions require that all three instructions be placed
++ * consecutively in memory.
+ */
+ if (aarch64_insn_uses_literal(insn) ||
+- aarch64_insn_is_exclusive(insn))
++ aarch64_insn_is_exclusive(insn) ||
++ aarch64_insn_is_mops(insn))
+ return false;
+
+ return true;
+diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
+index 0fcc4eb1a7abcc..385fb78845d696 100644
+--- a/arch/arm64/kernel/process.c
++++ b/arch/arm64/kernel/process.c
+@@ -429,7 +429,7 @@ static void tls_thread_switch(struct task_struct *next)
+
+ if (is_compat_thread(task_thread_info(next)))
+ write_sysreg(next->thread.uw.tp_value, tpidrro_el0);
+- else if (!arm64_kernel_unmapped_at_el0())
++ else
+ write_sysreg(0, tpidrro_el0);
+
+ write_sysreg(*task_user_tls(next), tpidr_el0);
+diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
+index c583d1f335f8c7..040b0175334c05 100644
+--- a/arch/arm64/kernel/setup.c
++++ b/arch/arm64/kernel/setup.c
+@@ -190,7 +190,11 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
+ if (dt_virt)
+ memblock_reserve(dt_phys, size);
+
+- if (!dt_virt || !early_init_dt_scan(dt_virt)) {
++ /*
++ * dt_virt is a fixmap address, hence __pa(dt_virt) can't be used.
++ * Pass dt_phys directly.
++ */
++ if (!early_init_dt_scan(dt_virt, dt_phys)) {
+ pr_crit("\n"
+ "Error: invalid device tree blob at physical address %pa (virtual address 0x%px)\n"
+ "The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
+diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
+index 3cd7e76cc56266..a553dae9a0d482 100644
+--- a/arch/arm64/kernel/vmlinux.lds.S
++++ b/arch/arm64/kernel/vmlinux.lds.S
+@@ -285,6 +285,9 @@ SECTIONS
+ __initdata_end = .;
+ __init_end = .;
+
++ .data.rel.ro : { *(.data.rel.ro) }
++ ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
++
+ _data = .;
+ _sdata = .;
+ RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
+@@ -336,9 +339,6 @@ SECTIONS
+ *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
+ }
+ ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
+-
+- .data.rel.ro : { *(.data.rel.ro) }
+- ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
+ }
+
+ #include "image-vars.h"
+diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
+index a1e24228aaaa76..d221829502f3e0 100644
+--- a/arch/arm64/kvm/arch_timer.c
++++ b/arch/arm64/kvm/arch_timer.c
+@@ -206,8 +206,7 @@ void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
+
+ static inline bool userspace_irqchip(struct kvm *kvm)
+ {
+- return static_branch_unlikely(&userspace_irqchip_in_use) &&
+- unlikely(!irqchip_in_kernel(kvm));
++ return unlikely(!irqchip_in_kernel(kvm));
+ }
+
+ static void soft_timer_start(struct hrtimer *hrt, u64 ns)
+diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
+index 18413d869cca1a..4742e6c5ea7a00 100644
+--- a/arch/arm64/kvm/arm.c
++++ b/arch/arm64/kvm/arm.c
+@@ -57,7 +57,6 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
+ static bool vgic_present, kvm_arm_initialised;
+
+ static DEFINE_PER_CPU(unsigned char, kvm_hyp_initialized);
+-DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
+
+ bool is_kvm_arm_initialised(void)
+ {
+@@ -401,9 +400,6 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
+
+ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
+ {
+- if (vcpu_has_run_once(vcpu) && unlikely(!irqchip_in_kernel(vcpu->kvm)))
+- static_branch_dec(&userspace_irqchip_in_use);
+-
+ kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+ kvm_timer_vcpu_terminate(vcpu);
+ kvm_pmu_vcpu_destroy(vcpu);
+@@ -627,14 +623,6 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
+ return ret;
+ }
+
+- if (!irqchip_in_kernel(kvm)) {
+- /*
+- * Tell the rest of the code that there are userspace irqchip
+- * VMs in the wild.
+- */
+- static_branch_inc(&userspace_irqchip_in_use);
+- }
+-
+ /*
+ * Initialize traps for protected VMs.
+ * NOTE: Move to run in EL2 directly, rather than via a hypercall, once
+@@ -856,7 +844,7 @@ static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret)
+ * state gets updated in kvm_timer_update_run and
+ * kvm_pmu_update_run below).
+ */
+- if (static_branch_unlikely(&userspace_irqchip_in_use)) {
++ if (unlikely(!irqchip_in_kernel(vcpu->kvm))) {
+ if (kvm_timer_should_notify_user(vcpu) ||
+ kvm_pmu_should_notify_user(vcpu)) {
+ *ret = -EINTR;
+@@ -975,7 +963,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
+ vcpu->mode = OUTSIDE_GUEST_MODE;
+ isb(); /* Ensure work in x_flush_hwstate is committed */
+ kvm_pmu_sync_hwstate(vcpu);
+- if (static_branch_unlikely(&userspace_irqchip_in_use))
++ if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
+ kvm_timer_sync_user(vcpu);
+ kvm_vgic_sync_hwstate(vcpu);
+ local_irq_enable();
+@@ -1021,7 +1009,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
+ * we don't want vtimer interrupts to race with syncing the
+ * timer virtual interrupt state.
+ */
+- if (static_branch_unlikely(&userspace_irqchip_in_use))
++ if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
+ kvm_timer_sync_user(vcpu);
+
+ kvm_arch_vcpu_ctxsync_fp(vcpu);
+diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
+index 6b066e04dc5dfe..3867d6d1f5d1bd 100644
+--- a/arch/arm64/kvm/pmu-emul.c
++++ b/arch/arm64/kvm/pmu-emul.c
+@@ -326,7 +326,6 @@ static u64 kvm_pmu_overflow_status(struct kvm_vcpu *vcpu)
+
+ if ((__vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E)) {
+ reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
+- reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0);
+ reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
+ }
+
+diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
+index 4f9084ba7949c0..608c39859f4ec3 100644
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -855,6 +855,9 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,
+
+ ite = find_ite(its, device_id, event_id);
+ if (ite && its_is_collection_mapped(ite->collection)) {
++ struct its_device *device = find_its_device(its, device_id);
++ int ite_esz = vgic_its_get_abi(its)->ite_esz;
++ gpa_t gpa = device->itt_addr + ite->event_id * ite_esz;
+ /*
+ * Though the spec talks about removing the pending state, we
+ * don't bother here since we clear the ITTE anyway and the
+@@ -863,7 +866,8 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,
+ vgic_its_invalidate_cache(kvm);
+
+ its_free_ite(kvm, ite);
+- return 0;
++
++ return vgic_its_write_entry_lock(its, gpa, 0, ite_esz);
+ }
+
+ return E_ITS_DISCARD_UNMAPPED_INTERRUPT;
+@@ -1211,9 +1215,11 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
+ bool valid = its_cmd_get_validbit(its_cmd);
+ u8 num_eventid_bits = its_cmd_get_size(its_cmd);
+ gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd);
++ int dte_esz = vgic_its_get_abi(its)->dte_esz;
+ struct its_device *device;
++ gpa_t gpa;
+
+- if (!vgic_its_check_id(its, its->baser_device_table, device_id, NULL))
++ if (!vgic_its_check_id(its, its->baser_device_table, device_id, &gpa))
+ return E_ITS_MAPD_DEVICE_OOR;
+
+ if (valid && num_eventid_bits > VITS_TYPER_IDBITS)
+@@ -1234,7 +1240,7 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
+ * is an error, so we are done in any case.
+ */
+ if (!valid)
+- return 0;
++ return vgic_its_write_entry_lock(its, gpa, 0, dte_esz);
+
+ device = vgic_its_alloc_device(its, device_id, itt_addr,
+ num_eventid_bits);
+@@ -2207,7 +2213,6 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
+ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
+ struct its_ite *ite, gpa_t gpa, int ite_esz)
+ {
+- struct kvm *kvm = its->dev->kvm;
+ u32 next_offset;
+ u64 val;
+
+@@ -2216,7 +2221,8 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
+ ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) |
+ ite->collection->collection_id;
+ val = cpu_to_le64(val);
+- return vgic_write_guest_lock(kvm, gpa, &val, ite_esz);
++
++ return vgic_its_write_entry_lock(its, gpa, val, ite_esz);
+ }
+
+ /**
+@@ -2357,7 +2363,6 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev)
+ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
+ gpa_t ptr, int dte_esz)
+ {
+- struct kvm *kvm = its->dev->kvm;
+ u64 val, itt_addr_field;
+ u32 next_offset;
+
+@@ -2368,7 +2373,8 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
+ (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
+ (dev->num_eventid_bits - 1));
+ val = cpu_to_le64(val);
+- return vgic_write_guest_lock(kvm, ptr, &val, dte_esz);
++
++ return vgic_its_write_entry_lock(its, ptr, val, dte_esz);
+ }
+
+ /**
+@@ -2555,7 +2561,8 @@ static int vgic_its_save_cte(struct vgic_its *its,
+ ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) |
+ collection->collection_id);
+ val = cpu_to_le64(val);
+- return vgic_write_guest_lock(its->dev->kvm, gpa, &val, esz);
++
++ return vgic_its_write_entry_lock(its, gpa, val, esz);
+ }
+
+ /*
+@@ -2571,8 +2578,7 @@ static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
+ u64 val;
+ int ret;
+
+- BUG_ON(esz > sizeof(val));
+- ret = kvm_read_guest_lock(kvm, gpa, &val, esz);
++ ret = vgic_its_read_entry_lock(its, gpa, &val, esz);
+ if (ret)
+ return ret;
+ val = le64_to_cpu(val);
+@@ -2610,7 +2616,6 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
+ u64 baser = its->baser_coll_table;
+ gpa_t gpa = GITS_BASER_ADDR_48_to_52(baser);
+ struct its_collection *collection;
+- u64 val;
+ size_t max_size, filled = 0;
+ int ret, cte_esz = abi->cte_esz;
+
+@@ -2634,10 +2639,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
+ * table is not fully filled, add a last dummy element
+ * with valid bit unset
+ */
+- val = 0;
+- BUG_ON(cte_esz > sizeof(val));
+- ret = vgic_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz);
+- return ret;
++ return vgic_its_write_entry_lock(its, gpa, 0, cte_esz);
+ }
+
+ /**
+diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+index 48e8b60ff1e338..7c0b23415ad9b0 100644
+--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
++++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+@@ -555,6 +555,7 @@ static void vgic_mmio_write_invlpi(struct kvm_vcpu *vcpu,
+ unsigned long val)
+ {
+ struct vgic_irq *irq;
++ u32 intid;
+
+ /*
+ * If the guest wrote only to the upper 32bit part of the
+@@ -566,9 +567,13 @@ static void vgic_mmio_write_invlpi(struct kvm_vcpu *vcpu,
+ if ((addr & 4) || !vgic_lpis_enabled(vcpu))
+ return;
+
++ intid = lower_32_bits(val);
++ if (intid < VGIC_MIN_LPI)
++ return;
++
+ vgic_set_rdist_busy(vcpu, true);
+
+- irq = vgic_get_irq(vcpu->kvm, NULL, lower_32_bits(val));
++ irq = vgic_get_irq(vcpu->kvm, NULL, intid);
+ if (irq) {
+ vgic_its_inv_lpi(vcpu->kvm, irq);
+ vgic_put_irq(vcpu->kvm, irq);
+diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
+index 07e48f8a4f23b3..3fa68827dc89fc 100644
+--- a/arch/arm64/kvm/vgic/vgic.h
++++ b/arch/arm64/kvm/vgic/vgic.h
+@@ -145,6 +145,29 @@ static inline int vgic_write_guest_lock(struct kvm *kvm, gpa_t gpa,
+ return ret;
+ }
+
++static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr,
++ u64 *eval, unsigned long esize)
++{
++ struct kvm *kvm = its->dev->kvm;
++
++ if (KVM_BUG_ON(esize != sizeof(*eval), kvm))
++ return -EINVAL;
++
++ return kvm_read_guest_lock(kvm, eaddr, eval, esize);
++
++}
++
++static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr,
++ u64 eval, unsigned long esize)
++{
++ struct kvm *kvm = its->dev->kvm;
++
++ if (KVM_BUG_ON(esize != sizeof(eval), kvm))
++ return -EINVAL;
++
++ return vgic_write_guest_lock(kvm, eaddr, &eval, esize);
++}
++
+ /*
+ * This struct provides an intermediate representation of the fields contained
+ * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC
+diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
+index 166619348b98e4..5074bd1d37b5f6 100644
+--- a/arch/arm64/net/bpf_jit_comp.c
++++ b/arch/arm64/net/bpf_jit_comp.c
+@@ -1816,6 +1816,12 @@ static void restore_args(struct jit_ctx *ctx, int args_off, int nregs)
+ }
+ }
+
++static bool is_struct_ops_tramp(const struct bpf_tramp_links *fentry_links)
++{
++ return fentry_links->nr_links == 1 &&
++ fentry_links->links[0]->link.type == BPF_LINK_TYPE_STRUCT_OPS;
++}
++
+ /* Based on the x86's implementation of arch_prepare_bpf_trampoline().
+ *
+ * bpf prog and function entry before bpf trampoline hooked:
+@@ -1845,6 +1851,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
+ struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
+ bool save_ret;
+ __le32 **branches = NULL;
++ bool is_struct_ops = is_struct_ops_tramp(fentry);
+
+ /* trampoline stack layout:
+ * [ parent ip ]
+@@ -1913,11 +1920,14 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
+ */
+ emit_bti(A64_BTI_JC, ctx);
+
+- /* frame for parent function */
+- emit(A64_PUSH(A64_FP, A64_R(9), A64_SP), ctx);
+- emit(A64_MOV(1, A64_FP, A64_SP), ctx);
++ /* x9 is not set for struct_ops */
++ if (!is_struct_ops) {
++ /* frame for parent function */
++ emit(A64_PUSH(A64_FP, A64_R(9), A64_SP), ctx);
++ emit(A64_MOV(1, A64_FP, A64_SP), ctx);
++ }
+
+- /* frame for patched function */
++ /* frame for patched function for tracing, or caller for struct_ops */
+ emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
+ emit(A64_MOV(1, A64_FP, A64_SP), ctx);
+
+@@ -2003,19 +2013,24 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
+ /* reset SP */
+ emit(A64_MOV(1, A64_SP, A64_FP), ctx);
+
+- /* pop frames */
+- emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
+- emit(A64_POP(A64_FP, A64_R(9), A64_SP), ctx);
+-
+- if (flags & BPF_TRAMP_F_SKIP_FRAME) {
+- /* skip patched function, return to parent */
+- emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
+- emit(A64_RET(A64_R(9)), ctx);
++ if (is_struct_ops) {
++ emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
++ emit(A64_RET(A64_LR), ctx);
+ } else {
+- /* return to patched function */
+- emit(A64_MOV(1, A64_R(10), A64_LR), ctx);
+- emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
+- emit(A64_RET(A64_R(10)), ctx);
++ /* pop frames */
++ emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
++ emit(A64_POP(A64_FP, A64_R(9), A64_SP), ctx);
++
++ if (flags & BPF_TRAMP_F_SKIP_FRAME) {
++ /* skip patched function, return to parent */
++ emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
++ emit(A64_RET(A64_R(9)), ctx);
++ } else {
++ /* return to patched function */
++ emit(A64_MOV(1, A64_R(10), A64_LR), ctx);
++ emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
++ emit(A64_RET(A64_R(10)), ctx);
++ }
+ }
+
+ if (ctx->image)
+diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c
+index 106fbf0b6f3b40..2d85484ae0e7ef 100644
+--- a/arch/csky/kernel/setup.c
++++ b/arch/csky/kernel/setup.c
+@@ -124,9 +124,9 @@ asmlinkage __visible void __init csky_start(unsigned int unused,
+ pre_trap_init();
+
+ if (dtb_start == NULL)
+- early_init_dt_scan(__dtb_start);
++ early_init_dt_scan(__dtb_start, __pa(dtb_start));
+ else
+- early_init_dt_scan(dtb_start);
++ early_init_dt_scan(dtb_start, __pa(dtb_start));
+
+ start_kernel();
+
+diff --git a/arch/loongarch/include/asm/page.h b/arch/loongarch/include/asm/page.h
+index 63f137ce82a41f..f49c2782c5c4db 100644
+--- a/arch/loongarch/include/asm/page.h
++++ b/arch/loongarch/include/asm/page.h
+@@ -94,10 +94,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
+ extern int __virt_addr_valid(volatile void *kaddr);
+ #define virt_addr_valid(kaddr) __virt_addr_valid((volatile void *)(kaddr))
+
+-#define VM_DATA_DEFAULT_FLAGS \
+- (VM_READ | VM_WRITE | \
+- ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC
+
+ #include <asm-generic/memory_model.h>
+ #include <asm-generic/getorder.h>
+diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
+index 065f2db57c0992..7ef1c1ff1fc44c 100644
+--- a/arch/loongarch/kernel/setup.c
++++ b/arch/loongarch/kernel/setup.c
+@@ -304,7 +304,7 @@ static void __init fdt_setup(void)
+ if (!fdt_pointer || fdt_check_header(fdt_pointer))
+ return;
+
+- early_init_dt_scan(fdt_pointer);
++ early_init_dt_scan(fdt_pointer, __pa(fdt_pointer));
+ early_init_fdt_reserve_self();
+
+ max_low_pfn = PFN_PHYS(memblock_end_of_DRAM());
+diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
+index 9eb7753d117dfb..497f8b0a5f1efb 100644
+--- a/arch/loongarch/net/bpf_jit.c
++++ b/arch/loongarch/net/bpf_jit.c
+@@ -179,7 +179,7 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call)
+
+ if (!is_tail_call) {
+ /* Set return value */
+- move_reg(ctx, LOONGARCH_GPR_A0, regmap[BPF_REG_0]);
++ emit_insn(ctx, addiw, LOONGARCH_GPR_A0, regmap[BPF_REG_0], 0);
+ /* Return to the caller */
+ emit_insn(ctx, jirl, LOONGARCH_GPR_RA, LOONGARCH_GPR_ZERO, 0);
+ } else {
+diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
+index f597cd08a96be0..1a0f6ca0247b4c 100644
+--- a/arch/loongarch/vdso/Makefile
++++ b/arch/loongarch/vdso/Makefile
+@@ -22,7 +22,7 @@ ccflags-vdso := \
+ cflags-vdso := $(ccflags-vdso) \
+ -isystem $(shell $(CC) -print-file-name=include) \
+ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
+- -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \
++ -std=gnu11 -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \
+ -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
+ $(call cc-option, -fno-asynchronous-unwind-tables) \
+ $(call cc-option, -fno-stack-protector)
+diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c
+index 7dab46728aedaf..b6958ec2a220cf 100644
+--- a/arch/m68k/coldfire/device.c
++++ b/arch/m68k/coldfire/device.c
+@@ -93,7 +93,7 @@ static struct platform_device mcf_uart = {
+ .dev.platform_data = mcf_uart_platform_data,
+ };
+
+-#if IS_ENABLED(CONFIG_FEC)
++#ifdef MCFFEC_BASE0
+
+ #ifdef CONFIG_M5441x
+ #define FEC_NAME "enet-fec"
+@@ -145,6 +145,7 @@ static struct platform_device mcf_fec0 = {
+ .platform_data = FEC_PDATA,
+ }
+ };
++#endif /* MCFFEC_BASE0 */
+
+ #ifdef MCFFEC_BASE1
+ static struct resource mcf_fec1_resources[] = {
+@@ -182,7 +183,6 @@ static struct platform_device mcf_fec1 = {
+ }
+ };
+ #endif /* MCFFEC_BASE1 */
+-#endif /* CONFIG_FEC */
+
+ #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
+ /*
+@@ -624,12 +624,12 @@ static struct platform_device mcf_flexcan0 = {
+
+ static struct platform_device *mcf_devices[] __initdata = {
+ &mcf_uart,
+-#if IS_ENABLED(CONFIG_FEC)
++#ifdef MCFFEC_BASE0
+ &mcf_fec0,
++#endif
+ #ifdef MCFFEC_BASE1
+ &mcf_fec1,
+ #endif
+-#endif
+ #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
+ &mcf_qspi,
+ #endif
+diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h
+index 7abd322c019fc1..295624d01d3dcd 100644
+--- a/arch/m68k/include/asm/mcfgpio.h
++++ b/arch/m68k/include/asm/mcfgpio.h
+@@ -136,7 +136,7 @@ static inline void gpio_free(unsigned gpio)
+ * read-modify-write as well as those controlled by the EPORT and GPIO modules.
+ */
+ #define MCFGPIO_SCR_START 40
+-#elif defined(CONFIGM5441x)
++#elif defined(CONFIG_M5441x)
+ /* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */
+ #define MCFGPIO_SCR_START 0
+ #else
+diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h
+index e28eb1c0e0bfb3..dbf88059e47a4d 100644
+--- a/arch/m68k/include/asm/mvme147hw.h
++++ b/arch/m68k/include/asm/mvme147hw.h
+@@ -93,8 +93,8 @@ struct pcc_regs {
+ #define M147_SCC_B_ADDR 0xfffe3000
+ #define M147_SCC_PCLK 5000000
+
+-#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45)
+-#define MVME147_IRQ_SCSI_DMA (IRQ_USER+0x46)
++#define MVME147_IRQ_SCSI_PORT (IRQ_USER + 5)
++#define MVME147_IRQ_SCSI_DMA (IRQ_USER + 6)
+
+ /* SCC interrupts, for MVME147 */
+
+diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c
+index 7d3fe08a48eb03..f11ef9f1f56fcf 100644
+--- a/arch/m68k/kernel/early_printk.c
++++ b/arch/m68k/kernel/early_printk.c
+@@ -12,8 +12,9 @@
+ #include <linux/string.h>
+ #include <asm/setup.h>
+
+-extern void mvme16x_cons_write(struct console *co,
+- const char *str, unsigned count);
++
++#include "../mvme147/mvme147.h"
++#include "../mvme16x/mvme16x.h"
+
+ asmlinkage void __init debug_cons_nputs(const char *s, unsigned n);
+
+@@ -22,7 +23,9 @@ static void __ref debug_cons_write(struct console *c,
+ {
+ #if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \
+ defined(CONFIG_COLDFIRE))
+- if (MACH_IS_MVME16x)
++ if (MACH_IS_MVME147)
++ mvme147_scc_write(c, s, n);
++ else if (MACH_IS_MVME16x)
+ mvme16x_cons_write(c, s, n);
+ else
+ debug_cons_nputs(s, n);
+diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
+index 4e6218115f43ce..95d4a7e13b33d5 100644
+--- a/arch/m68k/mvme147/config.c
++++ b/arch/m68k/mvme147/config.c
+@@ -35,6 +35,7 @@
+ #include <asm/mvme147hw.h>
+ #include <asm/config.h>
+
++#include "mvme147.h"
+
+ static void mvme147_get_model(char *model);
+ extern void mvme147_sched_init(void);
+@@ -188,3 +189,32 @@ int mvme147_hwclk(int op, struct rtc_time *t)
+ }
+ return 0;
+ }
++
++static void scc_delay(void)
++{
++ __asm__ __volatile__ ("nop; nop;");
++}
++
++static void scc_write(char ch)
++{
++ do {
++ scc_delay();
++ } while (!(in_8(M147_SCC_A_ADDR) & BIT(2)));
++ scc_delay();
++ out_8(M147_SCC_A_ADDR, 8);
++ scc_delay();
++ out_8(M147_SCC_A_ADDR, ch);
++}
++
++void mvme147_scc_write(struct console *co, const char *str, unsigned int count)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ while (count--) {
++ if (*str == '\n')
++ scc_write('\r');
++ scc_write(*str++);
++ }
++ local_irq_restore(flags);
++}
+diff --git a/arch/m68k/mvme147/mvme147.h b/arch/m68k/mvme147/mvme147.h
+new file mode 100644
+index 00000000000000..140bc98b0102aa
+--- /dev/null
++++ b/arch/m68k/mvme147/mvme147.h
+@@ -0,0 +1,6 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++struct console;
++
++/* config.c */
++void mvme147_scc_write(struct console *co, const char *str, unsigned int count);
+diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
+index f00c7aa058dec2..2b7eac224138e2 100644
+--- a/arch/m68k/mvme16x/config.c
++++ b/arch/m68k/mvme16x/config.c
+@@ -38,6 +38,8 @@
+ #include <asm/mvme16xhw.h>
+ #include <asm/config.h>
+
++#include "mvme16x.h"
++
+ extern t_bdid mvme_bdid;
+
+ static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
+diff --git a/arch/m68k/mvme16x/mvme16x.h b/arch/m68k/mvme16x/mvme16x.h
+new file mode 100644
+index 00000000000000..159c34b7003941
+--- /dev/null
++++ b/arch/m68k/mvme16x/mvme16x.h
+@@ -0,0 +1,6 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++struct console;
++
++/* config.c */
++void mvme16x_cons_write(struct console *co, const char *str, unsigned count);
+diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
+index c892e173ec990b..a8553f54152b76 100644
+--- a/arch/microblaze/kernel/microblaze_ksyms.c
++++ b/arch/microblaze/kernel/microblaze_ksyms.c
+@@ -16,6 +16,7 @@
+ #include <asm/page.h>
+ #include <linux/ftrace.h>
+ #include <linux/uaccess.h>
++#include <asm/xilinx_mb_manager.h>
+
+ #ifdef CONFIG_FUNCTION_TRACER
+ extern void _mcount(void);
+@@ -46,3 +47,12 @@ extern void __udivsi3(void);
+ EXPORT_SYMBOL(__udivsi3);
+ extern void __umodsi3(void);
+ EXPORT_SYMBOL(__umodsi3);
++
++#ifdef CONFIG_MB_MANAGER
++extern void xmb_manager_register(uintptr_t phys_baseaddr, u32 cr_val,
++ void (*callback)(void *data),
++ void *priv, void (*reset_callback)(void *data));
++EXPORT_SYMBOL(xmb_manager_register);
++extern asmlinkage void xmb_inject_err(void);
++EXPORT_SYMBOL(xmb_inject_err);
++#endif
+diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
+index e424c796e297c5..76ac4cfdfb42ce 100644
+--- a/arch/microblaze/kernel/prom.c
++++ b/arch/microblaze/kernel/prom.c
+@@ -18,7 +18,7 @@ void __init early_init_devtree(void *params)
+ {
+ pr_debug(" -> early_init_devtree(%p)\n", params);
+
+- early_init_dt_scan(params);
++ early_init_dt_scan(params, __pa(params));
+ if (!strlen(boot_command_line))
+ strscpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+
+diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h
+index a4374b4cb88fd8..d6ccd534402133 100644
+--- a/arch/mips/include/asm/switch_to.h
++++ b/arch/mips/include/asm/switch_to.h
+@@ -97,7 +97,7 @@ do { \
+ } \
+ } while (0)
+ #else
+-# define __sanitize_fcr31(next)
++# define __sanitize_fcr31(next) do { (void) (next); } while (0)
+ #endif
+
+ /*
+diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
+index f88ce78e13e3a2..474dc1eec3bb5d 100644
+--- a/arch/mips/kernel/prom.c
++++ b/arch/mips/kernel/prom.c
+@@ -39,7 +39,7 @@ char *mips_get_machine_name(void)
+
+ void __init __dt_setup_arch(void *bph)
+ {
+- if (!early_init_dt_scan(bph))
++ if (!early_init_dt_scan(bph, __pa(bph)))
+ return;
+
+ mips_set_machine_name(of_flat_dt_get_machine_name());
+diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c
+index 58fc8d089402bd..6d35d4f7ebe196 100644
+--- a/arch/mips/kernel/relocate.c
++++ b/arch/mips/kernel/relocate.c
+@@ -337,7 +337,7 @@ void *__init relocate_kernel(void)
+ #if defined(CONFIG_USE_OF)
+ /* Deal with the device tree */
+ fdt = plat_get_fdt();
+- early_init_dt_scan(fdt);
++ early_init_dt_scan(fdt, __pa(fdt));
+ if (boot_command_line[0]) {
+ /* Boot command line was passed in device tree */
+ strscpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c
+index 8d98af5c7201bb..15bbdd78e9bf20 100644
+--- a/arch/nios2/kernel/prom.c
++++ b/arch/nios2/kernel/prom.c
+@@ -26,12 +26,12 @@ void __init early_init_devtree(void *params)
+ if (be32_to_cpup((__be32 *)CONFIG_NIOS2_DTB_PHYS_ADDR) ==
+ OF_DT_HEADER) {
+ params = (void *)CONFIG_NIOS2_DTB_PHYS_ADDR;
+- early_init_dt_scan(params);
++ early_init_dt_scan(params, __pa(params));
+ return;
+ }
+ #endif
+ if (be32_to_cpu((__be32) *dtb) == OF_DT_HEADER)
+ params = (void *)__dtb_start;
+
+- early_init_dt_scan(params);
++ early_init_dt_scan(params, __pa(params));
+ }
+diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
+index fd9bb76a610bf0..206a6da4f31b0c 100644
+--- a/arch/openrisc/Kconfig
++++ b/arch/openrisc/Kconfig
+@@ -64,6 +64,9 @@ config STACKTRACE_SUPPORT
+ config LOCKDEP_SUPPORT
+ def_bool y
+
++config FIX_EARLYCON_MEM
++ def_bool y
++
+ menu "Processor type and features"
+
+ choice
+diff --git a/arch/openrisc/include/asm/fixmap.h b/arch/openrisc/include/asm/fixmap.h
+index ad78e50b7ba327..aece6013fead1f 100644
+--- a/arch/openrisc/include/asm/fixmap.h
++++ b/arch/openrisc/include/asm/fixmap.h
+@@ -26,29 +26,18 @@
+ #include <linux/bug.h>
+ #include <asm/page.h>
+
+-/*
+- * On OpenRISC we use these special fixed_addresses for doing ioremap
+- * early in the boot process before memory initialization is complete.
+- * This is used, in particular, by the early serial console code.
+- *
+- * It's not really 'fixmap', per se, but fits loosely into the same
+- * paradigm.
+- */
+ enum fixed_addresses {
+- /*
+- * FIX_IOREMAP entries are useful for mapping physical address
+- * space before ioremap() is useable, e.g. really early in boot
+- * before kmalloc() is working.
+- */
+-#define FIX_N_IOREMAPS 32
+- FIX_IOREMAP_BEGIN,
+- FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
++ FIX_EARLYCON_MEM_BASE,
+ __end_of_fixed_addresses
+ };
+
+ #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
+ /* FIXADDR_BOTTOM might be a better name here... */
+ #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
++#define FIXMAP_PAGE_IO PAGE_KERNEL_NOCACHE
++
++extern void __set_fixmap(enum fixed_addresses idx,
++ phys_addr_t phys, pgprot_t flags);
+
+ #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+ #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+diff --git a/arch/openrisc/kernel/prom.c b/arch/openrisc/kernel/prom.c
+index 19e6008bf114c6..e424e9bd12a793 100644
+--- a/arch/openrisc/kernel/prom.c
++++ b/arch/openrisc/kernel/prom.c
+@@ -22,6 +22,6 @@
+
+ void __init early_init_devtree(void *params)
+ {
+- early_init_dt_scan(params);
++ early_init_dt_scan(params, __pa(params));
+ memblock_allow_resize();
+ }
+diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c
+index 1dcd78c8f0e99b..d0cb1a0126f95d 100644
+--- a/arch/openrisc/mm/init.c
++++ b/arch/openrisc/mm/init.c
+@@ -207,6 +207,43 @@ void __init mem_init(void)
+ return;
+ }
+
++static int __init map_page(unsigned long va, phys_addr_t pa, pgprot_t prot)
++{
++ p4d_t *p4d;
++ pud_t *pud;
++ pmd_t *pmd;
++ pte_t *pte;
++
++ p4d = p4d_offset(pgd_offset_k(va), va);
++ pud = pud_offset(p4d, va);
++ pmd = pmd_offset(pud, va);
++ pte = pte_alloc_kernel(pmd, va);
++
++ if (pte == NULL)
++ return -ENOMEM;
++
++ if (pgprot_val(prot))
++ set_pte_at(&init_mm, va, pte, pfn_pte(pa >> PAGE_SHIFT, prot));
++ else
++ pte_clear(&init_mm, va, pte);
++
++ local_flush_tlb_page(NULL, va);
++ return 0;
++}
++
++void __init __set_fixmap(enum fixed_addresses idx,
++ phys_addr_t phys, pgprot_t prot)
++{
++ unsigned long address = __fix_to_virt(idx);
++
++ if (idx >= __end_of_fixed_addresses) {
++ BUG();
++ return;
++ }
++
++ map_page(address, phys, prot);
++}
++
+ static const pgprot_t protection_map[16] = {
+ [VM_NONE] = PAGE_NONE,
+ [VM_READ] = PAGE_READONLY_X,
+diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
+index c91f9c2e61ed25..f8d08eab7db8b0 100644
+--- a/arch/parisc/kernel/ftrace.c
++++ b/arch/parisc/kernel/ftrace.c
+@@ -87,7 +87,7 @@ int ftrace_enable_ftrace_graph_caller(void)
+
+ int ftrace_disable_ftrace_graph_caller(void)
+ {
+- static_key_enable(&ftrace_graph_enable.key);
++ static_key_disable(&ftrace_graph_enable.key);
+ return 0;
+ }
+ #endif
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 2fe51e0ad63713..6baa8b85601aa2 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -271,8 +271,8 @@ config PPC
+ select HAVE_RSEQ
+ select HAVE_SETUP_PER_CPU_AREA if PPC64
+ select HAVE_SOFTIRQ_ON_OWN_STACK
+- select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
+- select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13)
++ select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,$(m32-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 -mstack-protector-guard-offset=0)
++ select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,$(m64-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 -mstack-protector-guard-offset=0)
+ select HAVE_STATIC_CALL if PPC32
+ select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_VIRT_CPU_ACCOUNTING
+diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
+index f19dbaa1d54136..46cbc8ead07d9d 100644
+--- a/arch/powerpc/Makefile
++++ b/arch/powerpc/Makefile
+@@ -89,13 +89,6 @@ KBUILD_AFLAGS += -m$(BITS)
+ KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION)
+ endif
+
+-cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard=tls
+-ifdef CONFIG_PPC64
+-cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r13
+-else
+-cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r2
+-endif
+-
+ LDFLAGS_vmlinux-y := -Bstatic
+ LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie
+ LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) += -z notext
+@@ -389,9 +382,11 @@ prepare: stack_protector_prepare
+ PHONY += stack_protector_prepare
+ stack_protector_prepare: prepare0
+ ifdef CONFIG_PPC64
+- $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h))
++ $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \
++ -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h))
+ else
+- $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h))
++ $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \
++ -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h))
+ endif
+ endif
+
+diff --git a/arch/powerpc/include/asm/dtl.h b/arch/powerpc/include/asm/dtl.h
+index d6f43d149f8dcb..a5c21bc623cb00 100644
+--- a/arch/powerpc/include/asm/dtl.h
++++ b/arch/powerpc/include/asm/dtl.h
+@@ -1,8 +1,8 @@
+ #ifndef _ASM_POWERPC_DTL_H
+ #define _ASM_POWERPC_DTL_H
+
++#include <linux/rwsem.h>
+ #include <asm/lppaca.h>
+-#include <linux/spinlock_types.h>
+
+ /*
+ * Layout of entries in the hypervisor's dispatch trace log buffer.
+@@ -35,7 +35,7 @@ struct dtl_entry {
+ #define DTL_LOG_ALL (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)
+
+ extern struct kmem_cache *dtl_cache;
+-extern rwlock_t dtl_access_lock;
++extern struct rw_semaphore dtl_access_lock;
+
+ extern void register_dtl_buffer(int cpu);
+ extern void alloc_dtl_buffers(unsigned long *time_limit);
+diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
+index 526a6a6473128a..daa44b2ef35ad0 100644
+--- a/arch/powerpc/include/asm/fadump.h
++++ b/arch/powerpc/include/asm/fadump.h
+@@ -32,4 +32,11 @@ extern int early_init_dt_scan_fw_dump(unsigned long node, const char *uname,
+ int depth, void *data);
+ extern int fadump_reserve_mem(void);
+ #endif
++
++#if defined(CONFIG_FA_DUMP) && defined(CONFIG_CMA)
++void fadump_cma_init(void);
++#else
++static inline void fadump_cma_init(void) { }
++#endif
++
+ #endif /* _ASM_POWERPC_FADUMP_H */
+diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
+index 50950deedb8734..e3d0e714ff280e 100644
+--- a/arch/powerpc/include/asm/sstep.h
++++ b/arch/powerpc/include/asm/sstep.h
+@@ -173,9 +173,4 @@ int emulate_step(struct pt_regs *regs, ppc_inst_t instr);
+ */
+ extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op);
+
+-extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
+- const void *mem, bool cross_endian);
+-extern void emulate_vsx_store(struct instruction_op *op,
+- const union vsx_reg *reg, void *mem,
+- bool cross_endian);
+ extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs);
+diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h
+index 7650b6ce14c85a..8d972bc98b55fe 100644
+--- a/arch/powerpc/include/asm/vdso.h
++++ b/arch/powerpc/include/asm/vdso.h
+@@ -25,6 +25,7 @@ int vdso_getcpu_init(void);
+ #ifdef __VDSO64__
+ #define V_FUNCTION_BEGIN(name) \
+ .globl name; \
++ .type name,@function; \
+ name: \
+
+ #define V_FUNCTION_END(name) \
+diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
+index c3fb9fdf5bd782..a84e75fff1dfe1 100644
+--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
++++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
+@@ -857,7 +857,7 @@ bool __init dt_cpu_ftrs_init(void *fdt)
+ using_dt_cpu_ftrs = false;
+
+ /* Setup and verify the FDT, if it fails we just bail */
+- if (!early_init_dt_verify(fdt))
++ if (!early_init_dt_verify(fdt, __pa(fdt)))
+ return false;
+
+ if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))
+diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
+index 3ff2da7b120b50..1866bac2340007 100644
+--- a/arch/powerpc/kernel/fadump.c
++++ b/arch/powerpc/kernel/fadump.c
+@@ -80,27 +80,23 @@ static struct cma *fadump_cma;
+ * But for some reason even if it fails we still have the memory reservation
+ * with us and we can still continue doing fadump.
+ */
+-static int __init fadump_cma_init(void)
++void __init fadump_cma_init(void)
+ {
+ unsigned long long base, size;
+ int rc;
+
+- if (!fw_dump.fadump_enabled)
+- return 0;
+-
++ if (!fw_dump.fadump_supported || !fw_dump.fadump_enabled ||
++ fw_dump.dump_active)
++ return;
+ /*
+ * Do not use CMA if user has provided fadump=nocma kernel parameter.
+- * Return 1 to continue with fadump old behaviour.
+ */
+- if (fw_dump.nocma)
+- return 1;
++ if (fw_dump.nocma || !fw_dump.boot_memory_size)
++ return;
+
+ base = fw_dump.reserve_dump_area_start;
+ size = fw_dump.boot_memory_size;
+
+- if (!size)
+- return 0;
+-
+ rc = cma_init_reserved_mem(base, size, 0, "fadump_cma", &fadump_cma);
+ if (rc) {
+ pr_err("Failed to init cma area for firmware-assisted dump,%d\n", rc);
+@@ -110,7 +106,7 @@ static int __init fadump_cma_init(void)
+ * blocked from production system usage. Hence return 1,
+ * so that we can continue with fadump.
+ */
+- return 1;
++ return;
+ }
+
+ /*
+@@ -127,10 +123,7 @@ static int __init fadump_cma_init(void)
+ cma_get_size(fadump_cma),
+ (unsigned long)cma_get_base(fadump_cma) >> 20,
+ fw_dump.reserve_dump_area_size);
+- return 1;
+ }
+-#else
+-static int __init fadump_cma_init(void) { return 1; }
+ #endif /* CONFIG_CMA */
+
+ /* Scan the Firmware Assisted dump configuration details. */
+@@ -647,8 +640,6 @@ int __init fadump_reserve_mem(void)
+
+ pr_info("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n",
+ (size >> 20), base, (memblock_phys_mem_size() >> 20));
+-
+- ret = fadump_cma_init();
+ }
+
+ return ret;
+diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
+index bf6d8ad3819e99..7d5eccf3f80d92 100644
+--- a/arch/powerpc/kernel/prom.c
++++ b/arch/powerpc/kernel/prom.c
+@@ -781,7 +781,7 @@ void __init early_init_devtree(void *params)
+ DBG(" -> early_init_devtree(%px)\n", params);
+
+ /* Too early to BUG_ON(), do it by hand */
+- if (!early_init_dt_verify(params))
++ if (!early_init_dt_verify(params, __pa(params)))
+ panic("BUG: Failed verifying flat device tree, bad version?");
+
+ of_scan_flat_dt(early_init_dt_scan_model, NULL);
+diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
+index 03eaad5949f141..d43db8150767be 100644
+--- a/arch/powerpc/kernel/setup-common.c
++++ b/arch/powerpc/kernel/setup-common.c
+@@ -988,9 +988,11 @@ void __init setup_arch(char **cmdline_p)
+ initmem_init();
+
+ /*
+- * Reserve large chunks of memory for use by CMA for KVM and hugetlb. These must
+- * be called after initmem_init(), so that pageblock_order is initialised.
++ * Reserve large chunks of memory for use by CMA for fadump, KVM and
++ * hugetlb. These must be called after initmem_init(), so that
++ * pageblock_order is initialised.
+ */
++ fadump_cma_init();
+ kvm_cma_reserve();
+ gigantic_hugetlb_cma_reserve();
+
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+index 394f209536cee0..a70fe396996423 100644
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -924,6 +924,7 @@ static int __init disable_hardlockup_detector(void)
+ hardlockup_detector_disable();
+ #else
+ if (firmware_has_feature(FW_FEATURE_LPAR)) {
++ check_kvm_guest();
+ if (is_kvm_guest())
+ hardlockup_detector_disable();
+ }
+diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
+index f420df7888a75c..7ab4e2fb28b1e3 100644
+--- a/arch/powerpc/kernel/vmlinux.lds.S
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -123,8 +123,6 @@ SECTIONS
+ */
+ *(.sfpr);
+ *(.text.asan.* .text.tsan.*)
+- MEM_KEEP(init.text)
+- MEM_KEEP(exit.text)
+ } :text
+
+ . = ALIGN(PAGE_SIZE);
+diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
+index a3de5369d22c23..7b71737ae24cc2 100644
+--- a/arch/powerpc/kexec/file_load_64.c
++++ b/arch/powerpc/kexec/file_load_64.c
+@@ -916,13 +916,18 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
+ if (dn) {
+ u64 val;
+
+- of_property_read_u64(dn, "opal-base-address", &val);
++ ret = of_property_read_u64(dn, "opal-base-address", &val);
++ if (ret)
++ goto out;
++
+ ret = kexec_purgatory_get_set_symbol(image, "opal_base", &val,
+ sizeof(val), false);
+ if (ret)
+ goto out;
+
+- of_property_read_u64(dn, "opal-entry-address", &val);
++ ret = of_property_read_u64(dn, "opal-entry-address", &val);
++ if (ret)
++ goto out;
+ ret = kexec_purgatory_get_set_symbol(image, "opal_entry", &val,
+ sizeof(val), false);
+ }
+diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
+index 1bb00c72154407..924689fa5efa15 100644
+--- a/arch/powerpc/kvm/book3s_hv.c
++++ b/arch/powerpc/kvm/book3s_hv.c
+@@ -4090,6 +4090,15 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns
+ }
+ hvregs.hdec_expiry = time_limit;
+
++ /*
++ * hvregs has the doorbell status, so zero it here which
++ * enables us to receive doorbells when H_ENTER_NESTED is
++ * in progress for this vCPU
++ */
++
++ if (vcpu->arch.doorbell_request)
++ vcpu->arch.doorbell_request = 0;
++
+ /*
+ * When setting DEC, we must always deal with irq_work_raise
+ * via NMI vs setting DEC. The problem occurs right as we
+@@ -4678,7 +4687,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
+ lpcr |= LPCR_MER;
+ }
+ } else if (vcpu->arch.pending_exceptions ||
+- vcpu->arch.doorbell_request ||
+ xive_interrupt_pending(vcpu)) {
+ vcpu->arch.ret = RESUME_HOST;
+ goto out;
+diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
+index 377d0b4a05eeb4..49144129da420e 100644
+--- a/arch/powerpc/kvm/book3s_hv_nested.c
++++ b/arch/powerpc/kvm/book3s_hv_nested.c
+@@ -32,7 +32,7 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
+ struct kvmppc_vcore *vc = vcpu->arch.vcore;
+
+ hr->pcr = vc->pcr | PCR_MASK;
+- hr->dpdes = vc->dpdes;
++ hr->dpdes = vcpu->arch.doorbell_request;
+ hr->hfscr = vcpu->arch.hfscr;
+ hr->tb_offset = vc->tb_offset;
+ hr->dawr0 = vcpu->arch.dawr0;
+@@ -105,7 +105,7 @@ static void save_hv_return_state(struct kvm_vcpu *vcpu,
+ {
+ struct kvmppc_vcore *vc = vcpu->arch.vcore;
+
+- hr->dpdes = vc->dpdes;
++ hr->dpdes = vcpu->arch.doorbell_request;
+ hr->purr = vcpu->arch.purr;
+ hr->spurr = vcpu->arch.spurr;
+ hr->ic = vcpu->arch.ic;
+@@ -143,7 +143,7 @@ static void restore_hv_regs(struct kvm_vcpu *vcpu, const struct hv_guest_state *
+ struct kvmppc_vcore *vc = vcpu->arch.vcore;
+
+ vc->pcr = hr->pcr | PCR_MASK;
+- vc->dpdes = hr->dpdes;
++ vcpu->arch.doorbell_request = hr->dpdes;
+ vcpu->arch.hfscr = hr->hfscr;
+ vcpu->arch.dawr0 = hr->dawr0;
+ vcpu->arch.dawrx0 = hr->dawrx0;
+@@ -170,7 +170,13 @@ void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu,
+ {
+ struct kvmppc_vcore *vc = vcpu->arch.vcore;
+
+- vc->dpdes = hr->dpdes;
++ /*
++ * This L2 vCPU might have received a doorbell while H_ENTER_NESTED was being handled.
++ * Make sure we preserve the doorbell if it was either:
++ * a) Sent after H_ENTER_NESTED was called on this vCPU (arch.doorbell_request would be 1)
++ * b) Doorbell was not handled and L2 exited for some other reason (hr->dpdes would be 1)
++ */
++ vcpu->arch.doorbell_request = vcpu->arch.doorbell_request | hr->dpdes;
+ vcpu->arch.hfscr = hr->hfscr;
+ vcpu->arch.purr = hr->purr;
+ vcpu->arch.spurr = hr->spurr;
+diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
+index 6af97dc0f6d5a8..efbf1807887086 100644
+--- a/arch/powerpc/lib/sstep.c
++++ b/arch/powerpc/lib/sstep.c
+@@ -780,8 +780,8 @@ static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea,
+ #endif /* __powerpc64 */
+
+ #ifdef CONFIG_VSX
+-void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
+- const void *mem, bool rev)
++static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
++ const void *mem, bool rev)
+ {
+ int size, read_size;
+ int i, j;
+@@ -863,11 +863,9 @@ void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
+ break;
+ }
+ }
+-EXPORT_SYMBOL_GPL(emulate_vsx_load);
+-NOKPROBE_SYMBOL(emulate_vsx_load);
+
+-void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
+- void *mem, bool rev)
++static nokprobe_inline void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
++ void *mem, bool rev)
+ {
+ int size, write_size;
+ int i, j;
+@@ -955,8 +953,6 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
+ break;
+ }
+ }
+-EXPORT_SYMBOL_GPL(emulate_vsx_store);
+-NOKPROBE_SYMBOL(emulate_vsx_store);
+
+ static nokprobe_inline int do_vsx_load(struct instruction_op *op,
+ unsigned long ea, struct pt_regs *regs,
+diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
+index b1723094d464cf..d3e0f5b3ecc74d 100644
+--- a/arch/powerpc/mm/fault.c
++++ b/arch/powerpc/mm/fault.c
+@@ -431,10 +431,16 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
+ /*
+ * The kernel should never take an execute fault nor should it
+ * take a page fault to a kernel address or a page fault to a user
+- * address outside of dedicated places
++ * address outside of dedicated places.
++ *
++ * Rather than kfence directly reporting false negatives, search whether
++ * the NIP belongs to the fixup table for cases where fault could come
++ * from functions like copy_from_kernel_nofault().
+ */
+ if (unlikely(!is_user && bad_kernel_fault(regs, error_code, address, is_write))) {
+- if (kfence_handle_page_fault(address, is_write, regs))
++ if (is_kfence_address((void *)address) &&
++ !search_exception_tables(instruction_pointer(regs)) &&
++ kfence_handle_page_fault(address, is_write, regs))
+ return 0;
+
+ return SIGSEGV;
+diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
+index 3f1cdccebc9c15..ecc04ef8c53e31 100644
+--- a/arch/powerpc/platforms/pseries/dtl.c
++++ b/arch/powerpc/platforms/pseries/dtl.c
+@@ -191,7 +191,7 @@ static int dtl_enable(struct dtl *dtl)
+ return -EBUSY;
+
+ /* ensure there are no other conflicting dtl users */
+- if (!read_trylock(&dtl_access_lock))
++ if (!down_read_trylock(&dtl_access_lock))
+ return -EBUSY;
+
+ n_entries = dtl_buf_entries;
+@@ -199,7 +199,7 @@ static int dtl_enable(struct dtl *dtl)
+ if (!buf) {
+ printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
+ __func__, dtl->cpu);
+- read_unlock(&dtl_access_lock);
++ up_read(&dtl_access_lock);
+ return -ENOMEM;
+ }
+
+@@ -217,7 +217,7 @@ static int dtl_enable(struct dtl *dtl)
+ spin_unlock(&dtl->lock);
+
+ if (rc) {
+- read_unlock(&dtl_access_lock);
++ up_read(&dtl_access_lock);
+ kmem_cache_free(dtl_cache, buf);
+ }
+
+@@ -232,7 +232,7 @@ static void dtl_disable(struct dtl *dtl)
+ dtl->buf = NULL;
+ dtl->buf_entries = 0;
+ spin_unlock(&dtl->lock);
+- read_unlock(&dtl_access_lock);
++ up_read(&dtl_access_lock);
+ }
+
+ /* file interface */
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+index c3585e90c6db6b..cade33aef41477 100644
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -169,7 +169,7 @@ struct vcpu_dispatch_data {
+ */
+ #define NR_CPUS_H NR_CPUS
+
+-DEFINE_RWLOCK(dtl_access_lock);
++DECLARE_RWSEM(dtl_access_lock);
+ static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data);
+ static DEFINE_PER_CPU(u64, dtl_entry_ridx);
+ static DEFINE_PER_CPU(struct dtl_worker, dtl_workers);
+@@ -463,7 +463,7 @@ static int dtl_worker_enable(unsigned long *time_limit)
+ {
+ int rc = 0, state;
+
+- if (!write_trylock(&dtl_access_lock)) {
++ if (!down_write_trylock(&dtl_access_lock)) {
+ rc = -EBUSY;
+ goto out;
+ }
+@@ -479,7 +479,7 @@ static int dtl_worker_enable(unsigned long *time_limit)
+ pr_err("vcpudispatch_stats: unable to setup workqueue for DTL processing\n");
+ free_dtl_buffers(time_limit);
+ reset_global_dtl_mask();
+- write_unlock(&dtl_access_lock);
++ up_write(&dtl_access_lock);
+ rc = -EINVAL;
+ goto out;
+ }
+@@ -494,7 +494,7 @@ static void dtl_worker_disable(unsigned long *time_limit)
+ cpuhp_remove_state(dtl_worker_state);
+ free_dtl_buffers(time_limit);
+ reset_global_dtl_mask();
+- write_unlock(&dtl_access_lock);
++ up_write(&dtl_access_lock);
+ }
+
+ static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p,
+diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
+index ed492d38f6ad6b..fe7a43a8a1f46d 100644
+--- a/arch/powerpc/platforms/pseries/plpks.c
++++ b/arch/powerpc/platforms/pseries/plpks.c
+@@ -683,7 +683,7 @@ void __init plpks_early_init_devtree(void)
+ out:
+ fdt_nop_property(fdt, chosen_node, "ibm,plpks-pw");
+ // Since we've cleared the password, we must update the FDT checksum
+- early_init_dt_verify(fdt);
++ early_init_dt_verify(fdt, __pa(fdt));
+ }
+
+ static __init int pseries_plpks_init(void)
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index ddadee6621f0da..1fa501b7d0c868 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -246,7 +246,7 @@ static void __init init_resources(void)
+ static void __init parse_dtb(void)
+ {
+ /* Early scan of device tree from init memory */
+- if (early_init_dt_scan(dtb_early_va)) {
++ if (early_init_dt_scan(dtb_early_va, __pa(dtb_early_va))) {
+ const char *name = of_flat_dt_get_machine_name();
+
+ if (name) {
+diff --git a/arch/riscv/kvm/aia_aplic.c b/arch/riscv/kvm/aia_aplic.c
+index b467ba5ed91000..9d5b04c971c4d9 100644
+--- a/arch/riscv/kvm/aia_aplic.c
++++ b/arch/riscv/kvm/aia_aplic.c
+@@ -143,7 +143,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
+ if (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH ||
+ sm == APLIC_SOURCECFG_SM_LEVEL_LOW) {
+ if (!pending)
+- goto skip_write_pending;
++ goto noskip_write_pending;
+ if ((irqd->state & APLIC_IRQ_STATE_INPUT) &&
+ sm == APLIC_SOURCECFG_SM_LEVEL_LOW)
+ goto skip_write_pending;
+@@ -152,6 +152,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
+ goto skip_write_pending;
+ }
+
++noskip_write_pending:
+ if (pending)
+ irqd->state |= APLIC_IRQ_STATE_PENDING;
+ else
+diff --git a/arch/s390/include/asm/set_memory.h b/arch/s390/include/asm/set_memory.h
+index 06fbabe2f66c98..cb4cc0f59012f7 100644
+--- a/arch/s390/include/asm/set_memory.h
++++ b/arch/s390/include/asm/set_memory.h
+@@ -62,5 +62,6 @@ __SET_MEMORY_FUNC(set_memory_4k, SET_MEMORY_4K)
+
+ int set_direct_map_invalid_noflush(struct page *page);
+ int set_direct_map_default_noflush(struct page *page);
++bool kernel_page_present(struct page *page);
+
+ #endif
+diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
+index 26c08ee8774077..ebad8c8b8c57dd 100644
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -458,9 +458,13 @@ SYM_CODE_START(\name)
+ SYM_CODE_END(\name)
+ .endm
+
++ .section .irqentry.text, "ax"
++
+ INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
+ INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
+
++ .section .kprobes.text, "ax"
++
+ /*
+ * Load idle PSW.
+ */
+diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
+index d4b863ed0aa75d..cb149a64dba646 100644
+--- a/arch/s390/kernel/kprobes.c
++++ b/arch/s390/kernel/kprobes.c
+@@ -518,6 +518,12 @@ int __init arch_init_kprobes(void)
+ return 0;
+ }
+
++int __init arch_populate_kprobe_blacklist(void)
++{
++ return kprobe_add_area_blacklist((unsigned long)__irqentry_text_start,
++ (unsigned long)__irqentry_text_end);
++}
++
+ int arch_trampoline_kprobe(struct kprobe *p)
+ {
+ return 0;
+diff --git a/arch/s390/kernel/syscalls/Makefile b/arch/s390/kernel/syscalls/Makefile
+index fb85e797946db6..2bd7756288df61 100644
+--- a/arch/s390/kernel/syscalls/Makefile
++++ b/arch/s390/kernel/syscalls/Makefile
+@@ -12,7 +12,7 @@ kapi-hdrs-y := $(kapi)/unistd_nr.h
+ uapi-hdrs-y := $(uapi)/unistd_32.h
+ uapi-hdrs-y += $(uapi)/unistd_64.h
+
+-targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
++targets += $(addprefix ../../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
+
+ PHONY += kapi uapi
+
+diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
+index 441f654d048d20..44271835c97e7d 100644
+--- a/arch/s390/mm/pageattr.c
++++ b/arch/s390/mm/pageattr.c
+@@ -406,6 +406,21 @@ int set_direct_map_default_noflush(struct page *page)
+ return __set_memory((unsigned long)page_to_virt(page), 1, SET_MEMORY_DEF);
+ }
+
++bool kernel_page_present(struct page *page)
++{
++ unsigned long addr;
++ unsigned int cc;
++
++ addr = (unsigned long)page_address(page);
++ asm volatile(
++ " lra %[addr],0(%[addr])\n"
++ " ipm %[cc]\n"
++ : [cc] "=d" (cc), [addr] "+a" (addr)
++ :
++ : "cc");
++ return (cc >> 28) == 0;
++}
++
+ #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
+
+ static void ipte_range(pte_t *pte, unsigned long address, int nr)
+diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c
+index a306bcd6b34130..5f6d0e827baeb0 100644
+--- a/arch/sh/kernel/cpu/proc.c
++++ b/arch/sh/kernel/cpu/proc.c
+@@ -132,7 +132,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
+
+ static void *c_start(struct seq_file *m, loff_t *pos)
+ {
+- return *pos < NR_CPUS ? cpu_data + *pos : NULL;
++ return *pos < nr_cpu_ids ? cpu_data + *pos : NULL;
+ }
+ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+ {
+diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
+index b3da2757faaf31..1fb59c69b97c85 100644
+--- a/arch/sh/kernel/setup.c
++++ b/arch/sh/kernel/setup.c
+@@ -260,7 +260,7 @@ void __ref sh_fdt_init(phys_addr_t dt_phys)
+ dt_virt = phys_to_virt(dt_phys);
+ #endif
+
+- if (!dt_virt || !early_init_dt_scan(dt_virt)) {
++ if (!dt_virt || !early_init_dt_scan(dt_virt, __pa(dt_virt))) {
+ pr_crit("Error: invalid device tree blob"
+ " at physical address %p\n", (void *)dt_phys);
+
+diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
+index cabcc501b448a3..de187e58dc2b19 100644
+--- a/arch/um/drivers/net_kern.c
++++ b/arch/um/drivers/net_kern.c
+@@ -336,7 +336,7 @@ static struct platform_driver uml_net_driver = {
+
+ static void net_device_release(struct device *dev)
+ {
+- struct uml_net *device = dev_get_drvdata(dev);
++ struct uml_net *device = container_of(dev, struct uml_net, pdev.dev);
+ struct net_device *netdev = device->dev;
+ struct uml_net_private *lp = netdev_priv(netdev);
+
+diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
+index ef7b4b911a455a..7ddda2c0ae436f 100644
+--- a/arch/um/drivers/ubd_kern.c
++++ b/arch/um/drivers/ubd_kern.c
+@@ -799,7 +799,7 @@ static int ubd_open_dev(struct ubd *ubd_dev)
+
+ static void ubd_device_release(struct device *dev)
+ {
+- struct ubd *ubd_dev = dev_get_drvdata(dev);
++ struct ubd *ubd_dev = container_of(dev, struct ubd, pdev.dev);
+
+ blk_mq_free_tag_set(&ubd_dev->tag_set);
+ *ubd_dev = ((struct ubd) DEFAULT_UBD);
+diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
+index 94a4dfac6c2368..2baa8d4a33ed3d 100644
+--- a/arch/um/drivers/vector_kern.c
++++ b/arch/um/drivers/vector_kern.c
+@@ -823,7 +823,8 @@ static struct platform_driver uml_net_driver = {
+
+ static void vector_device_release(struct device *dev)
+ {
+- struct vector_device *device = dev_get_drvdata(dev);
++ struct vector_device *device =
++ container_of(dev, struct vector_device, pdev.dev);
+ struct net_device *netdev = device->dev;
+
+ list_del(&device->list);
+diff --git a/arch/um/kernel/dtb.c b/arch/um/kernel/dtb.c
+index 484141b06938ff..8d78ced9e08f6d 100644
+--- a/arch/um/kernel/dtb.c
++++ b/arch/um/kernel/dtb.c
+@@ -16,16 +16,16 @@ void uml_dtb_init(void)
+ void *area;
+
+ area = uml_load_file(dtb, &size);
+- if (!area)
+- return;
+-
+- if (!early_init_dt_scan(area)) {
+- pr_err("invalid DTB %s\n", dtb);
+- memblock_free(area, size);
+- return;
++ if (area) {
++ if (!early_init_dt_scan(area, __pa(area))) {
++ pr_err("invalid DTB %s\n", dtb);
++ memblock_free(area, size);
++ return;
++ }
++
++ early_init_fdt_scan_reserved_mem();
+ }
+
+- early_init_fdt_scan_reserved_mem();
+ unflatten_device_tree();
+ }
+
+diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
+index 91485119ae67a7..4339580f5a4f64 100644
+--- a/arch/um/kernel/physmem.c
++++ b/arch/um/kernel/physmem.c
+@@ -80,10 +80,10 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
+ unsigned long len, unsigned long long highmem)
+ {
+ unsigned long reserve = reserve_end - start;
+- long map_size = len - reserve;
++ unsigned long map_size = len - reserve;
+ int err;
+
+- if(map_size <= 0) {
++ if (len <= reserve) {
+ os_warn("Too few physical memory! Needed=%lu, given=%lu\n",
+ reserve, len);
+ exit(1);
+@@ -94,7 +94,7 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
+ err = os_map_memory((void *) reserve_end, physmem_fd, reserve,
+ map_size, 1, 1, 1);
+ if (err < 0) {
+- os_warn("setup_physmem - mapping %ld bytes of memory at 0x%p "
++ os_warn("setup_physmem - mapping %lu bytes of memory at 0x%p "
+ "failed - errno = %d\n", map_size,
+ (void *) reserve_end, err);
+ exit(1);
+diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
+index 6daffb9d8a8d74..afe67d81614676 100644
+--- a/arch/um/kernel/process.c
++++ b/arch/um/kernel/process.c
+@@ -397,6 +397,6 @@ int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
+ {
+ int cpu = current_thread_info()->cpu;
+
+- return save_i387_registers(userspace_pid[cpu], (unsigned long *) fpu);
++ return save_i387_registers(userspace_pid[cpu], (unsigned long *) fpu) == 0;
+ }
+
+diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
+index 746715379f12a8..7e897e44a03da2 100644
+--- a/arch/um/kernel/sysrq.c
++++ b/arch/um/kernel/sysrq.c
+@@ -53,5 +53,5 @@ void show_stack(struct task_struct *task, unsigned long *stack,
+ }
+
+ printk("%sCall Trace:\n", loglvl);
+- dump_trace(current, &stackops, (void *)loglvl);
++ dump_trace(task ?: current, &stackops, (void *)loglvl);
+ }
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 3ff53a2d4ff084..c83582b5a010de 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -113,7 +113,8 @@ ifeq ($(CONFIG_X86_32),y)
+
+ ifeq ($(CONFIG_STACKPROTECTOR),y)
+ ifeq ($(CONFIG_SMP),y)
+- KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard
++ KBUILD_CFLAGS += -mstack-protector-guard-reg=fs \
++ -mstack-protector-guard-symbol=__ref_stack_chk_guard
+ else
+ KBUILD_CFLAGS += -mstack-protector-guard=global
+ endif
+diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S
+index 2eca5f43734feb..56b9cd32895e4b 100644
+--- a/arch/x86/coco/tdx/tdcall.S
++++ b/arch/x86/coco/tdx/tdcall.S
+@@ -40,49 +40,35 @@
+ .section .noinstr.text, "ax"
+
+ /*
+- * __tdx_module_call() - Used by TDX guests to request services from
+- * the TDX module (does not include VMM services) using TDCALL instruction.
++ * __tdcall() - Used by TDX guests to request services from the TDX
++ * module (does not include VMM services) using TDCALL instruction.
+ *
+- * Transforms function call register arguments into the TDCALL register ABI.
+- * After TDCALL operation, TDX module output is saved in @out (if it is
+- * provided by the user).
++ * __tdcall() function ABI:
+ *
+- *-------------------------------------------------------------------------
+- * TDCALL ABI:
+- *-------------------------------------------------------------------------
+- * Input Registers:
+- *
+- * RAX - TDCALL Leaf number.
+- * RCX,RDX,R8-R9 - TDCALL Leaf specific input registers.
+- *
+- * Output Registers:
+- *
+- * RAX - TDCALL instruction error code.
+- * RCX,RDX,R8-R11 - TDCALL Leaf specific output registers.
+- *
+- *-------------------------------------------------------------------------
++ * @fn (RDI) - TDCALL Leaf ID, moved to RAX
++ * @args (RSI) - struct tdx_module_args for input
+ *
+- * __tdx_module_call() function ABI:
++ * Return status of TDCALL via RAX.
++ */
++SYM_FUNC_START(__tdcall)
++ TDX_MODULE_CALL host=0
++SYM_FUNC_END(__tdcall)
++
++/*
++ * __tdcall_ret() - Used by TDX guests to request services from the TDX
++ * module (does not include VMM services) using TDCALL instruction, with
++ * saving output registers to the 'struct tdx_module_args' used as input.
+ *
+- * @fn (RDI) - TDCALL Leaf ID, moved to RAX
+- * @rcx (RSI) - Input parameter 1, moved to RCX
+- * @rdx (RDX) - Input parameter 2, moved to RDX
+- * @r8 (RCX) - Input parameter 3, moved to R8
+- * @r9 (R8) - Input parameter 4, moved to R9
++ * __tdcall_ret() function ABI:
+ *
+- * @out (R9) - struct tdx_module_output pointer
+- * stored temporarily in R12 (not
+- * shared with the TDX module). It
+- * can be NULL.
++ * @fn (RDI) - TDCALL Leaf ID, moved to RAX
++ * @args (RSI) - struct tdx_module_args for input and output
+ *
+ * Return status of TDCALL via RAX.
+ */
+-SYM_FUNC_START(__tdx_module_call)
+- FRAME_BEGIN
+- TDX_MODULE_CALL host=0
+- FRAME_END
+- RET
+-SYM_FUNC_END(__tdx_module_call)
++SYM_FUNC_START(__tdcall_ret)
++ TDX_MODULE_CALL host=0 ret=1
++SYM_FUNC_END(__tdcall_ret)
+
+ /*
+ * TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
+diff --git a/arch/x86/coco/tdx/tdx-shared.c b/arch/x86/coco/tdx/tdx-shared.c
+index ef20ddc37b58aa..a7396d0ddef9e6 100644
+--- a/arch/x86/coco/tdx/tdx-shared.c
++++ b/arch/x86/coco/tdx/tdx-shared.c
+@@ -5,7 +5,7 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len,
+ enum pg_level pg_level)
+ {
+ unsigned long accept_size = page_level_size(pg_level);
+- u64 tdcall_rcx;
++ struct tdx_module_args args = {};
+ u8 page_size;
+
+ if (!IS_ALIGNED(start, accept_size))
+@@ -34,8 +34,8 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len,
+ return 0;
+ }
+
+- tdcall_rcx = start | page_size;
+- if (__tdx_module_call(TDX_ACCEPT_PAGE, tdcall_rcx, 0, 0, 0, NULL))
++ args.rcx = start | page_size;
++ if (__tdcall(TDG_MEM_PAGE_ACCEPT, &args))
+ return 0;
+
+ return accept_size;
+@@ -45,7 +45,7 @@ bool tdx_accept_memory(phys_addr_t start, phys_addr_t end)
+ {
+ /*
+ * For shared->private conversion, accept the page using
+- * TDX_ACCEPT_PAGE TDX module call.
++ * TDG_MEM_PAGE_ACCEPT TDX module call.
+ */
+ while (start < end) {
+ unsigned long len = end - start;
+diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
+index 905ac8a3f7165c..2f67e196a2ead2 100644
+--- a/arch/x86/coco/tdx/tdx.c
++++ b/arch/x86/coco/tdx/tdx.c
+@@ -68,13 +68,38 @@ EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);
+ * should only be used for calls that have no legitimate reason to fail
+ * or where the kernel can not survive the call failing.
+ */
+-static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
+- struct tdx_module_output *out)
++static inline void tdcall(u64 fn, struct tdx_module_args *args)
+ {
+- if (__tdx_module_call(fn, rcx, rdx, r8, r9, out))
++ if (__tdcall_ret(fn, args))
+ panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
+ }
+
++/* Read TD-scoped metadata */
++static inline u64 tdg_vm_rd(u64 field, u64 *value)
++{
++ struct tdx_module_args args = {
++ .rdx = field,
++ };
++ u64 ret;
++
++ ret = __tdcall_ret(TDG_VM_RD, &args);
++ *value = args.r8;
++
++ return ret;
++}
++
++/* Write TD-scoped metadata */
++static inline u64 tdg_vm_wr(u64 field, u64 value, u64 mask)
++{
++ struct tdx_module_args args = {
++ .rdx = field,
++ .r8 = value,
++ .r9 = mask,
++ };
++
++ return __tdcall(TDG_VM_WR, &args);
++}
++
+ /**
+ * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT
+ * subtype 0) using TDG.MR.REPORT TDCALL.
+@@ -91,11 +116,14 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
+ */
+ int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport)
+ {
++ struct tdx_module_args args = {
++ .rcx = virt_to_phys(tdreport),
++ .rdx = virt_to_phys(reportdata),
++ .r8 = TDREPORT_SUBTYPE_0,
++ };
+ u64 ret;
+
+- ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(tdreport),
+- virt_to_phys(reportdata), TDREPORT_SUBTYPE_0,
+- 0, NULL);
++ ret = __tdcall(TDG_MR_REPORT, &args);
+ if (ret) {
+ if (TDCALL_RETURN_CODE(ret) == TDCALL_INVALID_OPERAND)
+ return -EINVAL;
+@@ -141,9 +169,63 @@ static void __noreturn tdx_panic(const char *msg)
+ __tdx_hypercall(&args);
+ }
+
+-static void tdx_parse_tdinfo(u64 *cc_mask)
++/*
++ * The kernel cannot handle #VEs when accessing normal kernel memory. Ensure
++ * that no #VE will be delivered for accesses to TD-private memory.
++ *
++ * TDX 1.0 does not allow the guest to disable SEPT #VE on its own. The VMM
++ * controls if the guest will receive such #VE with TD attribute
++ * ATTR_SEPT_VE_DISABLE.
++ *
++ * Newer TDX modules allow the guest to control if it wants to receive SEPT
++ * violation #VEs.
++ *
++ * Check if the feature is available and disable SEPT #VE if possible.
++ *
++ * If the TD is allowed to disable/enable SEPT #VEs, the ATTR_SEPT_VE_DISABLE
++ * attribute is no longer reliable. It reflects the initial state of the
++ * control for the TD, but it will not be updated if someone (e.g. bootloader)
++ * changes it before the kernel starts. Kernel must check TDCS_TD_CTLS bit to
++ * determine if SEPT #VEs are enabled or disabled.
++ */
++static void disable_sept_ve(u64 td_attr)
++{
++ const char *msg = "TD misconfiguration: SEPT #VE has to be disabled";
++ bool debug = td_attr & ATTR_DEBUG;
++ u64 config, controls;
++
++ /* Is this TD allowed to disable SEPT #VE */
++ tdg_vm_rd(TDCS_CONFIG_FLAGS, &config);
++ if (!(config & TDCS_CONFIG_FLEXIBLE_PENDING_VE)) {
++ /* No SEPT #VE controls for the guest: check the attribute */
++ if (td_attr & ATTR_SEPT_VE_DISABLE)
++ return;
++
++ /* Relax SEPT_VE_DISABLE check for debug TD for backtraces */
++ if (debug)
++ pr_warn("%s\n", msg);
++ else
++ tdx_panic(msg);
++ return;
++ }
++
++ /* Check if SEPT #VE has been disabled before us */
++ tdg_vm_rd(TDCS_TD_CTLS, &controls);
++ if (controls & TD_CTLS_PENDING_VE_DISABLE)
++ return;
++
++ /* Keep #VEs enabled for splats in debugging environments */
++ if (debug)
++ return;
++
++ /* Disable SEPT #VEs */
++ tdg_vm_wr(TDCS_TD_CTLS, TD_CTLS_PENDING_VE_DISABLE,
++ TD_CTLS_PENDING_VE_DISABLE);
++}
++
++static void tdx_setup(u64 *cc_mask)
+ {
+- struct tdx_module_output out;
++ struct tdx_module_args args = {};
+ unsigned int gpa_width;
+ u64 td_attr;
+
+@@ -154,7 +236,7 @@ static void tdx_parse_tdinfo(u64 *cc_mask)
+ * Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL
+ * [TDG.VP.INFO].
+ */
+- tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
++ tdcall(TDG_VP_INFO, &args);
+
+ /*
+ * The highest bit of a guest physical address is the "sharing" bit.
+@@ -163,24 +245,15 @@ static void tdx_parse_tdinfo(u64 *cc_mask)
+ * The GPA width that comes out of this call is critical. TDX guests
+ * can not meaningfully run without it.
+ */
+- gpa_width = out.rcx & GENMASK(5, 0);
++ gpa_width = args.rcx & GENMASK(5, 0);
+ *cc_mask = BIT_ULL(gpa_width - 1);
+
+- /*
+- * The kernel can not handle #VE's when accessing normal kernel
+- * memory. Ensure that no #VE will be delivered for accesses to
+- * TD-private memory. Only VMM-shared memory (MMIO) will #VE.
+- */
+- td_attr = out.rdx;
+- if (!(td_attr & ATTR_SEPT_VE_DISABLE)) {
+- const char *msg = "TD misconfiguration: SEPT_VE_DISABLE attribute must be set.";
++ td_attr = args.rdx;
+
+- /* Relax SEPT_VE_DISABLE check for debug TD. */
+- if (td_attr & ATTR_DEBUG)
+- pr_warn("%s\n", msg);
+- else
+- tdx_panic(msg);
+- }
++ /* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */
++ tdg_vm_wr(TDCS_NOTIFY_ENABLES, 0, -1ULL);
++
++ disable_sept_ve(td_attr);
+ }
+
+ /*
+@@ -583,7 +656,7 @@ __init bool tdx_early_handle_ve(struct pt_regs *regs)
+
+ void tdx_get_ve_info(struct ve_info *ve)
+ {
+- struct tdx_module_output out;
++ struct tdx_module_args args = {};
+
+ /*
+ * Called during #VE handling to retrieve the #VE info from the
+@@ -600,15 +673,15 @@ void tdx_get_ve_info(struct ve_info *ve)
+ * Note, the TDX module treats virtual NMIs as inhibited if the #VE
+ * valid flag is set. It means that NMI=>#VE will not result in a #DF.
+ */
+- tdx_module_call(TDX_GET_VEINFO, 0, 0, 0, 0, &out);
++ tdcall(TDG_VP_VEINFO_GET, &args);
+
+ /* Transfer the output parameters */
+- ve->exit_reason = out.rcx;
+- ve->exit_qual = out.rdx;
+- ve->gla = out.r8;
+- ve->gpa = out.r9;
+- ve->instr_len = lower_32_bits(out.r10);
+- ve->instr_info = upper_32_bits(out.r10);
++ ve->exit_reason = args.rcx;
++ ve->exit_qual = args.rdx;
++ ve->gla = args.r8;
++ ve->gpa = args.r9;
++ ve->instr_len = lower_32_bits(args.r10);
++ ve->instr_info = upper_32_bits(args.r10);
+ }
+
+ /*
+@@ -776,11 +849,11 @@ void __init tdx_early_init(void)
+ setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);
+
+ cc_vendor = CC_VENDOR_INTEL;
+- tdx_parse_tdinfo(&cc_mask);
+- cc_set_mask(cc_mask);
+
+- /* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */
+- tdx_module_call(TDX_WR, 0, TDCS_NOTIFY_ENABLES, 0, -1ULL, NULL);
++ /* Configure the TD */
++ tdx_setup(&cc_mask);
++
++ cc_set_mask(cc_mask);
+
+ /*
+ * All bits above GPA width are reserved and kernel treats shared bit
+diff --git a/arch/x86/crypto/aegis128-aesni-asm.S b/arch/x86/crypto/aegis128-aesni-asm.S
+index ad7f4c89162568..2de859173940eb 100644
+--- a/arch/x86/crypto/aegis128-aesni-asm.S
++++ b/arch/x86/crypto/aegis128-aesni-asm.S
+@@ -21,7 +21,7 @@
+ #define T1 %xmm7
+
+ #define STATEP %rdi
+-#define LEN %rsi
++#define LEN %esi
+ #define SRC %rdx
+ #define DST %rcx
+
+@@ -76,32 +76,32 @@ SYM_FUNC_START_LOCAL(__load_partial)
+ xor %r9d, %r9d
+ pxor MSG, MSG
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x1, %r8
+ jz .Lld_partial_1
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x1E, %r8
+ add SRC, %r8
+ mov (%r8), %r9b
+
+ .Lld_partial_1:
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x2, %r8
+ jz .Lld_partial_2
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x1C, %r8
+ add SRC, %r8
+ shl $0x10, %r9
+ mov (%r8), %r9w
+
+ .Lld_partial_2:
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x4, %r8
+ jz .Lld_partial_4
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x18, %r8
+ add SRC, %r8
+ shl $32, %r9
+@@ -111,11 +111,11 @@ SYM_FUNC_START_LOCAL(__load_partial)
+ .Lld_partial_4:
+ movq %r9, MSG
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x8, %r8
+ jz .Lld_partial_8
+
+- mov LEN, %r8
++ mov LEN, %r8d
+ and $0x10, %r8
+ add SRC, %r8
+ pslldq $8, MSG
+@@ -139,7 +139,7 @@ SYM_FUNC_END(__load_partial)
+ * %r10
+ */
+ SYM_FUNC_START_LOCAL(__store_partial)
+- mov LEN, %r8
++ mov LEN, %r8d
+ mov DST, %r9
+
+ movq T0, %r10
+@@ -677,7 +677,7 @@ SYM_TYPED_FUNC_START(crypto_aegis128_aesni_dec_tail)
+ call __store_partial
+
+ /* mask with byte count: */
+- movq LEN, T0
++ movd LEN, T0
+ punpcklbw T0, T0
+ punpcklbw T0, T0
+ punpcklbw T0, T0
+@@ -702,7 +702,8 @@ SYM_FUNC_END(crypto_aegis128_aesni_dec_tail)
+
+ /*
+ * void crypto_aegis128_aesni_final(void *state, void *tag_xor,
+- * u64 assoclen, u64 cryptlen);
++ * unsigned int assoclen,
++ * unsigned int cryptlen);
+ */
+ SYM_FUNC_START(crypto_aegis128_aesni_final)
+ FRAME_BEGIN
+@@ -715,8 +716,8 @@ SYM_FUNC_START(crypto_aegis128_aesni_final)
+ movdqu 0x40(STATEP), STATE4
+
+ /* prepare length block: */
+- movq %rdx, MSG
+- movq %rcx, T0
++ movd %edx, MSG
++ movd %ecx, T0
+ pslldq $8, T0
+ pxor T0, MSG
+ psllq $3, MSG /* multiply by 8 (to get bit count) */
+diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S
+index 34eca8015b64bc..2143358d0c4c74 100644
+--- a/arch/x86/entry/entry.S
++++ b/arch/x86/entry/entry.S
+@@ -48,3 +48,18 @@ EXPORT_SYMBOL_GPL(mds_verw_sel);
+
+ .popsection
+
++#ifndef CONFIG_X86_64
++/*
++ * Clang's implementation of TLS stack cookies requires the variable in
++ * question to be a TLS variable. If the variable happens to be defined as an
++ * ordinary variable with external linkage in the same compilation unit (which
++ * amounts to the whole of vmlinux with LTO enabled), Clang will drop the
++ * segment register prefix from the references, resulting in broken code. Work
++ * around this by avoiding the symbol used in -mstack-protector-guard-symbol=
++ * entirely in the C code, and use an alias emitted by the linker script
++ * instead.
++ */
++#ifdef CONFIG_STACKPROTECTOR
++EXPORT_SYMBOL(__ref_stack_chk_guard);
++#endif
++#endif
+diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
+index 688550e336ce17..37c8badd270155 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -5559,8 +5559,22 @@ default_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+ return attr->mode;
+ }
+
++static umode_t
++td_is_visible(struct kobject *kobj, struct attribute *attr, int i)
++{
++ /*
++ * Hide the perf metrics topdown events
++ * if the feature is not enumerated.
++ */
++ if (x86_pmu.num_topdown_events)
++ return x86_pmu.intel_cap.perf_metrics ? attr->mode : 0;
++
++ return attr->mode;
++}
++
+ static struct attribute_group group_events_td = {
+ .name = "events",
++ .is_visible = td_is_visible,
+ };
+
+ static struct attribute_group group_events_mem = {
+@@ -5762,9 +5776,27 @@ static umode_t hybrid_format_is_visible(struct kobject *kobj,
+ return (cpu >= 0) && (pmu->cpu_type & pmu_attr->pmu_type) ? attr->mode : 0;
+ }
+
++static umode_t hybrid_td_is_visible(struct kobject *kobj,
++ struct attribute *attr, int i)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct x86_hybrid_pmu *pmu =
++ container_of(dev_get_drvdata(dev), struct x86_hybrid_pmu, pmu);
++
++ if (!is_attr_for_this_pmu(kobj, attr))
++ return 0;
++
++
++ /* Only the big core supports perf metrics */
++ if (pmu->cpu_type == hybrid_big)
++ return pmu->intel_cap.perf_metrics ? attr->mode : 0;
++
++ return attr->mode;
++}
++
+ static struct attribute_group hybrid_group_events_td = {
+ .name = "events",
+- .is_visible = hybrid_events_is_visible,
++ .is_visible = hybrid_td_is_visible,
+ };
+
+ static struct attribute_group hybrid_group_events_mem = {
+diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
+index 4110246aba12c3..7ee8dc80a35935 100644
+--- a/arch/x86/events/intel/pt.c
++++ b/arch/x86/events/intel/pt.c
+@@ -827,11 +827,13 @@ static void pt_buffer_advance(struct pt_buffer *buf)
+ buf->cur_idx++;
+
+ if (buf->cur_idx == buf->cur->last) {
+- if (buf->cur == buf->last)
++ if (buf->cur == buf->last) {
+ buf->cur = buf->first;
+- else
++ buf->wrapped = true;
++ } else {
+ buf->cur = list_entry(buf->cur->list.next, struct topa,
+ list);
++ }
+ buf->cur_idx = 0;
+ }
+ }
+@@ -845,8 +847,11 @@ static void pt_buffer_advance(struct pt_buffer *buf)
+ static void pt_update_head(struct pt *pt)
+ {
+ struct pt_buffer *buf = perf_get_aux(&pt->handle);
++ bool wrapped = buf->wrapped;
+ u64 topa_idx, base, old;
+
++ buf->wrapped = false;
++
+ if (buf->single) {
+ local_set(&buf->data_size, buf->output_off);
+ return;
+@@ -864,7 +869,7 @@ static void pt_update_head(struct pt *pt)
+ } else {
+ old = (local64_xchg(&buf->head, base) &
+ ((buf->nr_pages << PAGE_SHIFT) - 1));
+- if (base < old)
++ if (base < old || (base == old && wrapped))
+ base += buf->nr_pages << PAGE_SHIFT;
+
+ local_add(base - old, &buf->data_size);
+diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
+index f5e46c04c145d0..a1b6c04b7f6848 100644
+--- a/arch/x86/events/intel/pt.h
++++ b/arch/x86/events/intel/pt.h
+@@ -65,6 +65,7 @@ struct pt_pmu {
+ * @head: logical write offset inside the buffer
+ * @snapshot: if this is for a snapshot/overwrite counter
+ * @single: use Single Range Output instead of ToPA
++ * @wrapped: buffer advance wrapped back to the first topa table
+ * @stop_pos: STOP topa entry index
+ * @intr_pos: INT topa entry index
+ * @stop_te: STOP topa entry pointer
+@@ -82,6 +83,7 @@ struct pt_buffer {
+ local64_t head;
+ bool snapshot;
+ bool single;
++ bool wrapped;
+ long stop_pos, intr_pos;
+ struct topa_entry *stop_te, *intr_te;
+ void **data_pages;
+diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
+index ed0eaf65c43721..c8cdc69aae098b 100644
+--- a/arch/x86/include/asm/amd_nb.h
++++ b/arch/x86/include/asm/amd_nb.h
+@@ -116,7 +116,10 @@ static inline bool amd_gart_present(void)
+
+ #define amd_nb_num(x) 0
+ #define amd_nb_has_feature(x) false
+-#define node_to_amd_nb(x) NULL
++static inline struct amd_northbridge *node_to_amd_nb(int node)
++{
++ return NULL;
++}
+ #define amd_gart_present(x) false
+
+ #endif
+diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h
+index 0e82074517f6b7..768076e6866844 100644
+--- a/arch/x86/include/asm/asm-prototypes.h
++++ b/arch/x86/include/asm/asm-prototypes.h
+@@ -19,3 +19,6 @@
+ extern void cmpxchg8b_emu(void);
+ #endif
+
++#if defined(__GENKSYMS__) && defined(CONFIG_STACKPROTECTOR)
++extern unsigned long __ref_stack_chk_guard;
++#endif
+diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
+index 7513b3bb69b7e4..aed99fb099d9c5 100644
+--- a/arch/x86/include/asm/shared/tdx.h
++++ b/arch/x86/include/asm/shared/tdx.h
+@@ -11,15 +11,24 @@
+ #define TDX_IDENT "IntelTDX "
+
+ /* TDX module Call Leaf IDs */
+-#define TDX_GET_INFO 1
+-#define TDX_GET_VEINFO 3
+-#define TDX_GET_REPORT 4
+-#define TDX_ACCEPT_PAGE 6
+-#define TDX_WR 8
+-
+-/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */
++#define TDG_VP_INFO 1
++#define TDG_VP_VEINFO_GET 3
++#define TDG_MR_REPORT 4
++#define TDG_MEM_PAGE_ACCEPT 6
++#define TDG_VM_RD 7
++#define TDG_VM_WR 8
++
++/* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */
++#define TDCS_CONFIG_FLAGS 0x1110000300000016
++#define TDCS_TD_CTLS 0x1110000300000017
+ #define TDCS_NOTIFY_ENABLES 0x9100000000000010
+
++/* TDCS_CONFIG_FLAGS bits */
++#define TDCS_CONFIG_FLEXIBLE_PENDING_VE BIT_ULL(1)
++
++/* TDCS_TD_CTLS bits */
++#define TD_CTLS_PENDING_VE_DISABLE BIT_ULL(0)
++
+ /* TDX hypercall Leaf IDs */
+ #define TDVMCALL_MAP_GPA 0x10001
+ #define TDVMCALL_REPORT_FATAL_ERROR 0x10003
+@@ -74,11 +83,11 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)
+ void __tdx_hypercall_failed(void);
+
+ /*
+- * Used in __tdx_module_call() to gather the output registers' values of the
++ * Used in __tdcall*() to gather the input/output registers' values of the
+ * TDCALL instruction when requesting services from the TDX module. This is a
+ * software only structure and not part of the TDX module/VMM ABI
+ */
+-struct tdx_module_output {
++struct tdx_module_args {
+ u64 rcx;
+ u64 rdx;
+ u64 r8;
+@@ -88,8 +97,8 @@ struct tdx_module_output {
+ };
+
+ /* Used to communicate with the TDX module */
+-u64 __tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
+- struct tdx_module_output *out);
++u64 __tdcall(u64 fn, struct tdx_module_args *args);
++u64 __tdcall_ret(u64 fn, struct tdx_module_args *args);
+
+ bool tdx_accept_memory(phys_addr_t start, phys_addr_t end);
+
+diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
+index dc3576303f1ade..50383bc46dd77d 100644
+--- a/arch/x86/kernel/asm-offsets.c
++++ b/arch/x86/kernel/asm-offsets.c
+@@ -68,12 +68,12 @@ static void __used common(void)
+ #endif
+
+ BLANK();
+- OFFSET(TDX_MODULE_rcx, tdx_module_output, rcx);
+- OFFSET(TDX_MODULE_rdx, tdx_module_output, rdx);
+- OFFSET(TDX_MODULE_r8, tdx_module_output, r8);
+- OFFSET(TDX_MODULE_r9, tdx_module_output, r9);
+- OFFSET(TDX_MODULE_r10, tdx_module_output, r10);
+- OFFSET(TDX_MODULE_r11, tdx_module_output, r11);
++ OFFSET(TDX_MODULE_rcx, tdx_module_args, rcx);
++ OFFSET(TDX_MODULE_rdx, tdx_module_args, rdx);
++ OFFSET(TDX_MODULE_r8, tdx_module_args, r8);
++ OFFSET(TDX_MODULE_r9, tdx_module_args, r9);
++ OFFSET(TDX_MODULE_r10, tdx_module_args, r10);
++ OFFSET(TDX_MODULE_r11, tdx_module_args, r11);
+
+ BLANK();
+ OFFSET(TDX_HYPERCALL_r8, tdx_hypercall_args, r8);
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 7a1e58fb43a033..852cc2ab4df946 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -2159,8 +2159,10 @@ void syscall_init(void)
+
+ #ifdef CONFIG_STACKPROTECTOR
+ DEFINE_PER_CPU(unsigned long, __stack_chk_guard);
++#ifndef CONFIG_SMP
+ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
+ #endif
++#endif
+
+ #endif /* CONFIG_X86_64 */
+
+diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
+index c13c9cb40b9b46..37ca25d82bbcdb 100644
+--- a/arch/x86/kernel/devicetree.c
++++ b/arch/x86/kernel/devicetree.c
+@@ -283,22 +283,24 @@ static void __init x86_flattree_get_config(void)
+ u32 size, map_len;
+ void *dt;
+
+- if (!initial_dtb)
+- return;
+-
+- map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
++ if (initial_dtb) {
++ map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
++
++ dt = early_memremap(initial_dtb, map_len);
++ size = fdt_totalsize(dt);
++ if (map_len < size) {
++ early_memunmap(dt, map_len);
++ dt = early_memremap(initial_dtb, size);
++ map_len = size;
++ }
+
+- dt = early_memremap(initial_dtb, map_len);
+- size = fdt_totalsize(dt);
+- if (map_len < size) {
+- early_memunmap(dt, map_len);
+- dt = early_memremap(initial_dtb, size);
+- map_len = size;
++ early_init_dt_verify(dt, __pa(dt));
+ }
+
+- early_init_dt_verify(dt);
+ unflatten_and_copy_device_tree();
+- early_memunmap(dt, map_len);
++
++ if (initial_dtb)
++ early_memunmap(dt, map_len);
+ }
+ #else
+ static inline void x86_flattree_get_config(void) { }
+diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
+index 7e574cf3bf8a29..7784076819de58 100644
+--- a/arch/x86/kernel/unwind_orc.c
++++ b/arch/x86/kernel/unwind_orc.c
+@@ -723,7 +723,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
+ state->sp = task->thread.sp + sizeof(*frame);
+ state->bp = READ_ONCE_NOCHECK(frame->bp);
+ state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
+- state->signal = (void *)state->ip == ret_from_fork;
++ state->signal = (void *)state->ip == ret_from_fork_asm;
+ }
+
+ if (get_stack_info((unsigned long *)state->sp, state->task,
+diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
+index 54a5596adaa61e..60eb8baa44d7b7 100644
+--- a/arch/x86/kernel/vmlinux.lds.S
++++ b/arch/x86/kernel/vmlinux.lds.S
+@@ -496,6 +496,9 @@ SECTIONS
+ ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
+ }
+
++/* needed for Clang - see arch/x86/entry/entry.S */
++PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);
++
+ /*
+ * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+ */
+diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c
+index 4a599130e9c994..b4c1119cc48b69 100644
+--- a/arch/x86/kvm/mmu/spte.c
++++ b/arch/x86/kvm/mmu/spte.c
+@@ -206,12 +206,20 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
+ spte |= PT_WRITABLE_MASK | shadow_mmu_writable_mask;
+
+ /*
+- * Optimization: for pte sync, if spte was writable the hash
+- * lookup is unnecessary (and expensive). Write protection
+- * is responsibility of kvm_mmu_get_page / kvm_mmu_sync_roots.
+- * Same reasoning can be applied to dirty page accounting.
++ * When overwriting an existing leaf SPTE, and the old SPTE was
++ * writable, skip trying to unsync shadow pages as any relevant
++ * shadow pages must already be unsync, i.e. the hash lookup is
++ * unnecessary (and expensive).
++ *
++ * The same reasoning applies to dirty page/folio accounting;
++ * KVM will mark the folio dirty using the old SPTE, thus
++ * there's no need to immediately mark the new SPTE as dirty.
++ *
++ * Note, both cases rely on KVM not changing PFNs without first
++ * zapping the old SPTE, which is guaranteed by both the shadow
++ * MMU and the TDP MMU.
+ */
+- if (is_writable_pte(old_spte))
++ if (is_last_spte(old_spte, level) && is_writable_pte(old_spte))
+ goto out;
+
+ /*
+diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S
+index c4365a05ab83b3..008a805522245f 100644
+--- a/arch/x86/platform/pvh/head.S
++++ b/arch/x86/platform/pvh/head.S
+@@ -100,7 +100,27 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
+ xor %edx, %edx
+ wrmsr
+
+- call xen_prepare_pvh
++ /*
++ * Calculate load offset and store in phys_base. __pa() needs
++ * phys_base set to calculate the hypercall page in xen_pvh_init().
++ */
++ movq %rbp, %rbx
++ subq $_pa(pvh_start_xen), %rbx
++ movq %rbx, phys_base(%rip)
++
++ /* Call xen_prepare_pvh() via the kernel virtual mapping */
++ leaq xen_prepare_pvh(%rip), %rax
++ subq phys_base(%rip), %rax
++ addq $__START_KERNEL_map, %rax
++ ANNOTATE_RETPOLINE_SAFE
++ call *%rax
++
++ /*
++ * Clear phys_base. __startup_64 will *add* to its value,
++ * so reset to 0.
++ */
++ xor %rbx, %rbx
++ movq %rbx, phys_base(%rip)
+
+ /* startup_64 expects boot_params in %rsi. */
+ mov $_pa(pvh_bootparams), %rsi
+diff --git a/arch/x86/virt/vmx/tdx/tdxcall.S b/arch/x86/virt/vmx/tdx/tdxcall.S
+index 49a54356ae9925..e9e19e7d77f818 100644
+--- a/arch/x86/virt/vmx/tdx/tdxcall.S
++++ b/arch/x86/virt/vmx/tdx/tdxcall.S
+@@ -1,5 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ #include <asm/asm-offsets.h>
++#include <asm/frame.h>
+ #include <asm/tdx.h>
+
+ /*
+@@ -16,35 +17,37 @@
+ * TDX module and hypercalls to the VMM.
+ * SEAMCALL - used by TDX hosts to make requests to the
+ * TDX module.
++ *
++ *-------------------------------------------------------------------------
++ * TDCALL/SEAMCALL ABI:
++ *-------------------------------------------------------------------------
++ * Input Registers:
++ *
++ * RAX - TDCALL/SEAMCALL Leaf number.
++ * RCX,RDX,R8-R11 - TDCALL/SEAMCALL Leaf specific input registers.
++ *
++ * Output Registers:
++ *
++ * RAX - TDCALL/SEAMCALL instruction error code.
++ * RCX,RDX,R8-R11 - TDCALL/SEAMCALL Leaf specific output registers.
++ *
++ *-------------------------------------------------------------------------
+ */
+-.macro TDX_MODULE_CALL host:req
+- /*
+- * R12 will be used as temporary storage for struct tdx_module_output
+- * pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL
+- * services supported by this function, it can be reused.
+- */
+-
+- /* Callee saved, so preserve it */
+- push %r12
+-
+- /*
+- * Push output pointer to stack.
+- * After the operation, it will be fetched into R12 register.
+- */
+- push %r9
++.macro TDX_MODULE_CALL host:req ret=0
++ FRAME_BEGIN
+
+- /* Mangle function call ABI into TDCALL/SEAMCALL ABI: */
+ /* Move Leaf ID to RAX */
+ mov %rdi, %rax
+- /* Move input 4 to R9 */
+- mov %r8, %r9
+- /* Move input 3 to R8 */
+- mov %rcx, %r8
+- /* Move input 1 to RCX */
+- mov %rsi, %rcx
+- /* Leave input param 2 in RDX */
+
+- .if \host
++ /* Move other input regs from 'struct tdx_module_args' */
++ movq TDX_MODULE_rcx(%rsi), %rcx
++ movq TDX_MODULE_rdx(%rsi), %rdx
++ movq TDX_MODULE_r8(%rsi), %r8
++ movq TDX_MODULE_r9(%rsi), %r9
++ movq TDX_MODULE_r10(%rsi), %r10
++ movq TDX_MODULE_r11(%rsi), %r11
++
++.if \host
+ seamcall
+ /*
+ * SEAMCALL instruction is essentially a VMExit from VMX root
+@@ -57,40 +60,31 @@
+ * This value will never be used as actual SEAMCALL error code as
+ * it is from the Reserved status code class.
+ */
+- jnc .Lno_vmfailinvalid
+- mov $TDX_SEAMCALL_VMFAILINVALID, %rax
+-.Lno_vmfailinvalid:
+-
+- .else
++ jc .Lseamcall_vmfailinvalid\@
++.else
+ tdcall
+- .endif
++.endif
+
+- /*
+- * Fetch output pointer from stack to R12 (It is used
+- * as temporary storage)
+- */
+- pop %r12
++.if \ret
++ /* Copy output registers to the structure */
++ movq %rcx, TDX_MODULE_rcx(%rsi)
++ movq %rdx, TDX_MODULE_rdx(%rsi)
++ movq %r8, TDX_MODULE_r8(%rsi)
++ movq %r9, TDX_MODULE_r9(%rsi)
++ movq %r10, TDX_MODULE_r10(%rsi)
++ movq %r11, TDX_MODULE_r11(%rsi)
++.endif
+
+- /*
+- * Since this macro can be invoked with NULL as an output pointer,
+- * check if caller provided an output struct before storing output
+- * registers.
+- *
+- * Update output registers, even if the call failed (RAX != 0).
+- * Other registers may contain details of the failure.
+- */
+- test %r12, %r12
+- jz .Lno_output_struct
++.if \host
++.Lout\@:
++.endif
++ FRAME_END
++ RET
+
+- /* Copy result registers to output struct: */
+- movq %rcx, TDX_MODULE_rcx(%r12)
+- movq %rdx, TDX_MODULE_rdx(%r12)
+- movq %r8, TDX_MODULE_r8(%r12)
+- movq %r9, TDX_MODULE_r9(%r12)
+- movq %r10, TDX_MODULE_r10(%r12)
+- movq %r11, TDX_MODULE_r11(%r12)
++.if \host
++.Lseamcall_vmfailinvalid\@:
++ mov $TDX_SEAMCALL_VMFAILINVALID, %rax
++ jmp .Lout\@
++.endif /* \host */
+
+-.Lno_output_struct:
+- /* Restore the state of R12 register */
+- pop %r12
+ .endm
+diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
+index 52d6e4870a04c9..124e84fd9a2960 100644
+--- a/arch/xtensa/kernel/setup.c
++++ b/arch/xtensa/kernel/setup.c
+@@ -228,7 +228,7 @@ static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
+
+ void __init early_init_devtree(void *params)
+ {
+- early_init_dt_scan(params);
++ early_init_dt_scan(params, __pa(params));
+ of_scan_flat_dt(xtensa_dt_io_area, NULL);
+
+ if (!command_line[0])
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 7e0dcded5713a0..dd8ca3f7ba60a1 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -582,23 +582,31 @@ static struct request *bfq_choose_req(struct bfq_data *bfqd,
+ #define BFQ_LIMIT_INLINE_DEPTH 16
+
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+-static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
++static bool bfqq_request_over_limit(struct bfq_data *bfqd,
++ struct bfq_io_cq *bic, blk_opf_t opf,
++ unsigned int act_idx, int limit)
+ {
+- struct bfq_data *bfqd = bfqq->bfqd;
+- struct bfq_entity *entity = &bfqq->entity;
+ struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH];
+ struct bfq_entity **entities = inline_entities;
+- int depth, level, alloc_depth = BFQ_LIMIT_INLINE_DEPTH;
+- int class_idx = bfqq->ioprio_class - 1;
++ int alloc_depth = BFQ_LIMIT_INLINE_DEPTH;
+ struct bfq_sched_data *sched_data;
++ struct bfq_entity *entity;
++ struct bfq_queue *bfqq;
+ unsigned long wsum;
+ bool ret = false;
+-
+- if (!entity->on_st_or_in_serv)
+- return false;
++ int depth;
++ int level;
+
+ retry:
+ spin_lock_irq(&bfqd->lock);
++ bfqq = bic_to_bfqq(bic, op_is_sync(opf), act_idx);
++ if (!bfqq)
++ goto out;
++
++ entity = &bfqq->entity;
++ if (!entity->on_st_or_in_serv)
++ goto out;
++
+ /* +1 for bfqq entity, root cgroup not included */
+ depth = bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup->level + 1;
+ if (depth > alloc_depth) {
+@@ -643,7 +651,7 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
+ * class.
+ */
+ wsum = 0;
+- for (i = 0; i <= class_idx; i++) {
++ for (i = 0; i <= bfqq->ioprio_class - 1; i++) {
+ wsum = wsum * IOPRIO_BE_NR +
+ sched_data->service_tree[i].wsum;
+ }
+@@ -666,7 +674,9 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
+ return ret;
+ }
+ #else
+-static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
++static bool bfqq_request_over_limit(struct bfq_data *bfqd,
++ struct bfq_io_cq *bic, blk_opf_t opf,
++ unsigned int act_idx, int limit)
+ {
+ return false;
+ }
+@@ -704,8 +714,9 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
+ }
+
+ for (act_idx = 0; bic && act_idx < bfqd->num_actuators; act_idx++) {
+- struct bfq_queue *bfqq =
+- bic_to_bfqq(bic, op_is_sync(opf), act_idx);
++ /* Fast path to check if bfqq is already allocated. */
++ if (!bic_to_bfqq(bic, op_is_sync(opf), act_idx))
++ continue;
+
+ /*
+ * Does queue (or any parent entity) exceed number of
+@@ -713,7 +724,7 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
+ * limit depth so that it cannot consume more
+ * available requests and thus starve other entities.
+ */
+- if (bfqq && bfqq_request_over_limit(bfqq, limit)) {
++ if (bfqq_request_over_limit(bfqd, bic, opf, act_idx, limit)) {
+ depth = 1;
+ break;
+ }
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index 07bf758c523a9c..889ac59759a26f 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -256,6 +256,14 @@ static bool bvec_split_segs(const struct queue_limits *lim,
+ return len > 0 || bv->bv_len > max_len;
+ }
+
++static unsigned int bio_split_alignment(struct bio *bio,
++ const struct queue_limits *lim)
++{
++ if (op_is_write(bio_op(bio)) && lim->zone_write_granularity)
++ return lim->zone_write_granularity;
++ return lim->logical_block_size;
++}
++
+ /**
+ * bio_split_rw - split a bio in two bios
+ * @bio: [in] bio to be split
+@@ -326,7 +334,7 @@ struct bio *bio_split_rw(struct bio *bio, const struct queue_limits *lim,
+ * split size so that each bio is properly block size aligned, even if
+ * we do not use the full hardware limits.
+ */
+- bytes = ALIGN_DOWN(bytes, lim->logical_block_size);
++ bytes = ALIGN_DOWN(bytes, bio_split_alignment(bio, lim));
+
+ /*
+ * Bio splitting may cause subtle trouble such as hang when doing sync
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 733d72f4d1cc9d..6c71add013bfc2 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -283,8 +283,9 @@ void blk_mq_quiesce_tagset(struct blk_mq_tag_set *set)
+ if (!blk_queue_skip_tagset_quiesce(q))
+ blk_mq_quiesce_queue_nowait(q);
+ }
+- blk_mq_wait_quiesce_done(set);
+ mutex_unlock(&set->tag_list_lock);
++
++ blk_mq_wait_quiesce_done(set);
+ }
+ EXPORT_SYMBOL_GPL(blk_mq_quiesce_tagset);
+
+@@ -2252,6 +2253,24 @@ void blk_mq_delay_run_hw_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs)
+ }
+ EXPORT_SYMBOL(blk_mq_delay_run_hw_queue);
+
++static inline bool blk_mq_hw_queue_need_run(struct blk_mq_hw_ctx *hctx)
++{
++ bool need_run;
++
++ /*
++ * When queue is quiesced, we may be switching io scheduler, or
++ * updating nr_hw_queues, or other things, and we can't run queue
++ * any more, even blk_mq_hctx_has_pending() can't be called safely.
++ *
++ * And queue will be rerun in blk_mq_unquiesce_queue() if it is
++ * quiesced.
++ */
++ __blk_mq_run_dispatch_ops(hctx->queue, false,
++ need_run = !blk_queue_quiesced(hctx->queue) &&
++ blk_mq_hctx_has_pending(hctx));
++ return need_run;
++}
++
+ /**
+ * blk_mq_run_hw_queue - Start to run a hardware queue.
+ * @hctx: Pointer to the hardware queue to run.
+@@ -2272,20 +2291,23 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
+
+ might_sleep_if(!async && hctx->flags & BLK_MQ_F_BLOCKING);
+
+- /*
+- * When queue is quiesced, we may be switching io scheduler, or
+- * updating nr_hw_queues, or other things, and we can't run queue
+- * any more, even __blk_mq_hctx_has_pending() can't be called safely.
+- *
+- * And queue will be rerun in blk_mq_unquiesce_queue() if it is
+- * quiesced.
+- */
+- __blk_mq_run_dispatch_ops(hctx->queue, false,
+- need_run = !blk_queue_quiesced(hctx->queue) &&
+- blk_mq_hctx_has_pending(hctx));
++ need_run = blk_mq_hw_queue_need_run(hctx);
++ if (!need_run) {
++ unsigned long flags;
+
+- if (!need_run)
+- return;
++ /*
++ * Synchronize with blk_mq_unquiesce_queue(), because we check
++ * if hw queue is quiesced locklessly above, we need the use
++ * ->queue_lock to make sure we see the up-to-date status to
++ * not miss rerunning the hw queue.
++ */
++ spin_lock_irqsave(&hctx->queue->queue_lock, flags);
++ need_run = blk_mq_hw_queue_need_run(hctx);
++ spin_unlock_irqrestore(&hctx->queue->queue_lock, flags);
++
++ if (!need_run)
++ return;
++ }
+
+ if (async || !cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)) {
+ blk_mq_delay_run_hw_queue(hctx, 0);
+@@ -2442,6 +2464,12 @@ void blk_mq_start_stopped_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
+ return;
+
+ clear_bit(BLK_MQ_S_STOPPED, &hctx->state);
++ /*
++ * Pairs with the smp_mb() in blk_mq_hctx_stopped() to order the
++ * clearing of BLK_MQ_S_STOPPED above and the checking of dispatch
++ * list in the subsequent routine.
++ */
++ smp_mb__after_atomic();
+ blk_mq_run_hw_queue(hctx, async);
+ }
+ EXPORT_SYMBOL_GPL(blk_mq_start_stopped_hw_queue);
+@@ -2668,6 +2696,7 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
+
+ if (blk_mq_hctx_stopped(hctx) || blk_queue_quiesced(rq->q)) {
+ blk_mq_insert_request(rq, 0);
++ blk_mq_run_hw_queue(hctx, false);
+ return;
+ }
+
+@@ -2698,6 +2727,7 @@ static blk_status_t blk_mq_request_issue_directly(struct request *rq, bool last)
+
+ if (blk_mq_hctx_stopped(hctx) || blk_queue_quiesced(rq->q)) {
+ blk_mq_insert_request(rq, 0);
++ blk_mq_run_hw_queue(hctx, false);
+ return BLK_STS_OK;
+ }
+
+diff --git a/block/blk-mq.h b/block/blk-mq.h
+index 1743857e0b01d9..cf9f21772ddc8e 100644
+--- a/block/blk-mq.h
++++ b/block/blk-mq.h
+@@ -228,6 +228,19 @@ static inline struct blk_mq_tags *blk_mq_tags_from_data(struct blk_mq_alloc_data
+
+ static inline bool blk_mq_hctx_stopped(struct blk_mq_hw_ctx *hctx)
+ {
++ /* Fast path: hardware queue is not stopped most of the time. */
++ if (likely(!test_bit(BLK_MQ_S_STOPPED, &hctx->state)))
++ return false;
++
++ /*
++ * This barrier is used to order adding of dispatch list before and
++ * the test of BLK_MQ_S_STOPPED below. Pairs with the memory barrier
++ * in blk_mq_start_stopped_hw_queue() so that dispatch code could
++ * either see BLK_MQ_S_STOPPED is cleared or dispatch list is not
++ * empty to avoid missing dispatching requests.
++ */
++ smp_mb();
++
+ return test_bit(BLK_MQ_S_STOPPED, &hctx->state);
+ }
+
+diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
+index d0d954fe9d54f3..7fc79e7dce44a9 100644
+--- a/crypto/pcrypt.c
++++ b/crypto/pcrypt.c
+@@ -117,8 +117,10 @@ static int pcrypt_aead_encrypt(struct aead_request *req)
+ err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu);
+ if (!err)
+ return -EINPROGRESS;
+- if (err == -EBUSY)
+- return -EAGAIN;
++ if (err == -EBUSY) {
++ /* try non-parallel mode */
++ return crypto_aead_encrypt(creq);
++ }
+
+ return err;
+ }
+@@ -166,8 +168,10 @@ static int pcrypt_aead_decrypt(struct aead_request *req)
+ err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu);
+ if (!err)
+ return -EINPROGRESS;
+- if (err == -EBUSY)
+- return -EAGAIN;
++ if (err == -EBUSY) {
++ /* try non-parallel mode */
++ return crypto_aead_decrypt(creq);
++ }
+
+ return err;
+ }
+diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
+index c0e77c1c8e09d6..eb6c2d3603874a 100644
+--- a/drivers/acpi/arm64/gtdt.c
++++ b/drivers/acpi/arm64/gtdt.c
+@@ -283,7 +283,7 @@ static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block,
+ if (frame->virt_irq > 0)
+ acpi_unregister_gsi(gtdt_frame->virtual_timer_interrupt);
+ frame->virt_irq = 0;
+- } while (i-- >= 0 && gtdt_frame--);
++ } while (i-- > 0 && gtdt_frame--);
+
+ return -EINVAL;
+ }
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 26d1beec99137e..ed02a2a9970aa3 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -1142,7 +1142,6 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+ return -EFAULT;
+ }
+ val = MASK_VAL_WRITE(reg, prev_val, val);
+- val |= prev_val;
+ }
+
+ switch (size) {
+diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
+index 0b18c6b46e65d8..f3133ba831c5e0 100644
+--- a/drivers/base/firmware_loader/main.c
++++ b/drivers/base/firmware_loader/main.c
+@@ -824,19 +824,18 @@ static void fw_log_firmware_info(const struct firmware *fw, const char *name, st
+ shash->tfm = alg;
+
+ if (crypto_shash_digest(shash, fw->data, fw->size, sha256buf) < 0)
+- goto out_shash;
++ goto out_free;
+
+ for (int i = 0; i < SHA256_DIGEST_SIZE; i++)
+ sprintf(&outbuf[i * 2], "%02x", sha256buf[i]);
+ outbuf[SHA256_BLOCK_SIZE] = 0;
+ dev_dbg(device, "Loaded FW: %s, sha256: %s\n", name, outbuf);
+
+-out_shash:
+- crypto_free_shash(alg);
+ out_free:
+ kfree(shash);
+ kfree(outbuf);
+ kfree(sha256buf);
++ crypto_free_shash(alg);
+ }
+ #else
+ static void fw_log_firmware_info(const struct firmware *fw, const char *name,
+diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
+index 45fd13ef13fc64..dceab5d013dec9 100644
+--- a/drivers/base/regmap/regmap-irq.c
++++ b/drivers/base/regmap/regmap-irq.c
+@@ -514,12 +514,16 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
+ return IRQ_NONE;
+ }
+
++static struct lock_class_key regmap_irq_lock_class;
++static struct lock_class_key regmap_irq_request_class;
++
+ static int regmap_irq_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
+ {
+ struct regmap_irq_chip_data *data = h->host_data;
+
+ irq_set_chip_data(virq, data);
++ irq_set_lockdep_class(virq, &regmap_irq_lock_class, &regmap_irq_request_class);
+ irq_set_chip(virq, &data->irq_chip);
+ irq_set_nested_thread(virq, 1);
+ irq_set_parent(virq, data->irq);
+diff --git a/drivers/block/brd.c b/drivers/block/brd.c
+index 970bd6ff38c491..d816d1512531e4 100644
+--- a/drivers/block/brd.c
++++ b/drivers/block/brd.c
+@@ -310,8 +310,40 @@ __setup("ramdisk_size=", ramdisk_size);
+ * (should share code eventually).
+ */
+ static LIST_HEAD(brd_devices);
++static DEFINE_MUTEX(brd_devices_mutex);
+ static struct dentry *brd_debugfs_dir;
+
++static struct brd_device *brd_find_or_alloc_device(int i)
++{
++ struct brd_device *brd;
++
++ mutex_lock(&brd_devices_mutex);
++ list_for_each_entry(brd, &brd_devices, brd_list) {
++ if (brd->brd_number == i) {
++ mutex_unlock(&brd_devices_mutex);
++ return ERR_PTR(-EEXIST);
++ }
++ }
++
++ brd = kzalloc(sizeof(*brd), GFP_KERNEL);
++ if (!brd) {
++ mutex_unlock(&brd_devices_mutex);
++ return ERR_PTR(-ENOMEM);
++ }
++ brd->brd_number = i;
++ list_add_tail(&brd->brd_list, &brd_devices);
++ mutex_unlock(&brd_devices_mutex);
++ return brd;
++}
++
++static void brd_free_device(struct brd_device *brd)
++{
++ mutex_lock(&brd_devices_mutex);
++ list_del(&brd->brd_list);
++ mutex_unlock(&brd_devices_mutex);
++ kfree(brd);
++}
++
+ static int brd_alloc(int i)
+ {
+ struct brd_device *brd;
+@@ -319,14 +351,9 @@ static int brd_alloc(int i)
+ char buf[DISK_NAME_LEN];
+ int err = -ENOMEM;
+
+- list_for_each_entry(brd, &brd_devices, brd_list)
+- if (brd->brd_number == i)
+- return -EEXIST;
+- brd = kzalloc(sizeof(*brd), GFP_KERNEL);
+- if (!brd)
+- return -ENOMEM;
+- brd->brd_number = i;
+- list_add_tail(&brd->brd_list, &brd_devices);
++ brd = brd_find_or_alloc_device(i);
++ if (IS_ERR(brd))
++ return PTR_ERR(brd);
+
+ xa_init(&brd->brd_pages);
+
+@@ -369,8 +396,7 @@ static int brd_alloc(int i)
+ out_cleanup_disk:
+ put_disk(disk);
+ out_free_dev:
+- list_del(&brd->brd_list);
+- kfree(brd);
++ brd_free_device(brd);
+ return err;
+ }
+
+@@ -389,8 +415,7 @@ static void brd_cleanup(void)
+ del_gendisk(brd->brd_disk);
+ put_disk(brd->brd_disk);
+ brd_free_pages(brd);
+- list_del(&brd->brd_list);
+- kfree(brd);
++ brd_free_device(brd);
+ }
+ }
+
+@@ -417,16 +442,6 @@ static int __init brd_init(void)
+ {
+ int err, i;
+
+- brd_check_and_reset_par();
+-
+- brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
+-
+- for (i = 0; i < rd_nr; i++) {
+- err = brd_alloc(i);
+- if (err)
+- goto out_free;
+- }
+-
+ /*
+ * brd module now has a feature to instantiate underlying device
+ * structure on-demand, provided that there is an access dev node.
+@@ -442,11 +457,18 @@ static int __init brd_init(void)
+ * dynamically.
+ */
+
++ brd_check_and_reset_par();
++
++ brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
++
+ if (__register_blkdev(RAMDISK_MAJOR, "ramdisk", brd_probe)) {
+ err = -EIO;
+ goto out_free;
+ }
+
++ for (i = 0; i < rd_nr; i++)
++ brd_alloc(i);
++
+ pr_info("brd: module loaded\n");
+ return 0;
+
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index f31607a24f5735..1105e8adf7f96f 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -713,12 +713,21 @@ static inline char *ublk_queue_cmd_buf(struct ublk_device *ub, int q_id)
+ return ublk_get_queue(ub, q_id)->io_cmd_buf;
+ }
+
++static inline int __ublk_queue_cmd_buf_size(int depth)
++{
++ return round_up(depth * sizeof(struct ublksrv_io_desc), PAGE_SIZE);
++}
++
+ static inline int ublk_queue_cmd_buf_size(struct ublk_device *ub, int q_id)
+ {
+ struct ublk_queue *ubq = ublk_get_queue(ub, q_id);
+
+- return round_up(ubq->q_depth * sizeof(struct ublksrv_io_desc),
+- PAGE_SIZE);
++ return __ublk_queue_cmd_buf_size(ubq->q_depth);
++}
++
++static int ublk_max_cmd_buf_size(void)
++{
++ return __ublk_queue_cmd_buf_size(UBLK_MAX_QUEUE_DEPTH);
+ }
+
+ static inline bool ublk_queue_can_use_recovery_reissue(
+@@ -1387,7 +1396,7 @@ static int ublk_ch_mmap(struct file *filp, struct vm_area_struct *vma)
+ {
+ struct ublk_device *ub = filp->private_data;
+ size_t sz = vma->vm_end - vma->vm_start;
+- unsigned max_sz = UBLK_MAX_QUEUE_DEPTH * sizeof(struct ublksrv_io_desc);
++ unsigned max_sz = ublk_max_cmd_buf_size();
+ unsigned long pfn, end, phys_off = vma->vm_pgoff << PAGE_SHIFT;
+ int q_id, ret = 0;
+
+@@ -2904,7 +2913,7 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
+ ret = ublk_ctrl_end_recovery(ub, cmd);
+ break;
+ default:
+- ret = -ENOTSUPP;
++ ret = -EOPNOTSUPP;
+ break;
+ }
+
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index 41b2fd7e1b9e50..997106fe73e49f 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -475,18 +475,18 @@ static bool virtblk_prep_rq_batch(struct request *req)
+ return virtblk_prep_rq(req->mq_hctx, vblk, req, vbr) == BLK_STS_OK;
+ }
+
+-static bool virtblk_add_req_batch(struct virtio_blk_vq *vq,
++static void virtblk_add_req_batch(struct virtio_blk_vq *vq,
+ struct request **rqlist)
+ {
++ struct request *req;
+ unsigned long flags;
+- int err;
+ bool kick;
+
+ spin_lock_irqsave(&vq->lock, flags);
+
+- while (!rq_list_empty(*rqlist)) {
+- struct request *req = rq_list_pop(rqlist);
++ while ((req = rq_list_pop(rqlist))) {
+ struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
++ int err;
+
+ err = virtblk_add_req(vq->vq, vbr);
+ if (err) {
+@@ -499,37 +499,33 @@ static bool virtblk_add_req_batch(struct virtio_blk_vq *vq,
+ kick = virtqueue_kick_prepare(vq->vq);
+ spin_unlock_irqrestore(&vq->lock, flags);
+
+- return kick;
++ if (kick)
++ virtqueue_notify(vq->vq);
+ }
+
+ static void virtio_queue_rqs(struct request **rqlist)
+ {
+- struct request *req, *next, *prev = NULL;
++ struct request *submit_list = NULL;
+ struct request *requeue_list = NULL;
++ struct request **requeue_lastp = &requeue_list;
++ struct virtio_blk_vq *vq = NULL;
++ struct request *req;
+
+- rq_list_for_each_safe(rqlist, req, next) {
+- struct virtio_blk_vq *vq = get_virtio_blk_vq(req->mq_hctx);
+- bool kick;
+-
+- if (!virtblk_prep_rq_batch(req)) {
+- rq_list_move(rqlist, &requeue_list, req, prev);
+- req = prev;
+- if (!req)
+- continue;
+- }
++ while ((req = rq_list_pop(rqlist))) {
++ struct virtio_blk_vq *this_vq = get_virtio_blk_vq(req->mq_hctx);
+
+- if (!next || req->mq_hctx != next->mq_hctx) {
+- req->rq_next = NULL;
+- kick = virtblk_add_req_batch(vq, rqlist);
+- if (kick)
+- virtqueue_notify(vq->vq);
++ if (vq && vq != this_vq)
++ virtblk_add_req_batch(vq, &submit_list);
++ vq = this_vq;
+
+- *rqlist = next;
+- prev = NULL;
+- } else
+- prev = req;
++ if (virtblk_prep_rq_batch(req))
++ rq_list_add(&submit_list, req); /* reverse order */
++ else
++ rq_list_add_tail(&requeue_lastp, req);
+ }
+
++ if (vq)
++ virtblk_add_req_batch(vq, &submit_list);
+ *rqlist = requeue_list;
+ }
+
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
+index 606f388c7a5716..c29c471b6a1826 100644
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1600,6 +1600,13 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page,
+ if (ret)
+ return ret;
+
++ /*
++ * We touched this entry so mark it as non-IDLE. This makes sure that
++ * we don't preserve IDLE flag and don't incorrectly pick this entry
++ * for different post-processing type (e.g. writeback).
++ */
++ zram_clear_flag(zram, index, ZRAM_IDLE);
++
+ class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old);
+ /*
+ * Iterate the secondary comp algorithms list (in order of priority)
+diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
+index 42b1062e33cd5d..78999f7f248cb2 100644
+--- a/drivers/char/tpm/tpm-chip.c
++++ b/drivers/char/tpm/tpm-chip.c
+@@ -519,10 +519,6 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+ {
+ struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
+
+- /* Give back zero bytes, as TPM chip has not yet fully resumed: */
+- if (chip->flags & TPM_CHIP_FLAG_SUSPENDED)
+- return 0;
+-
+ return tpm_get_random(chip, data, max);
+ }
+
+diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
+index 66b16d26eecc78..c8ea52dfa55678 100644
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -394,6 +394,13 @@ int tpm_pm_suspend(struct device *dev)
+ if (!chip)
+ return -ENODEV;
+
++ rc = tpm_try_get_ops(chip);
++ if (rc) {
++ /* Can be safely set out of locks, as no action cannot race: */
++ chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
++ goto out;
++ }
++
+ if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
+ goto suspended;
+
+@@ -401,19 +408,18 @@ int tpm_pm_suspend(struct device *dev)
+ !pm_suspend_via_firmware())
+ goto suspended;
+
+- rc = tpm_try_get_ops(chip);
+- if (!rc) {
+- if (chip->flags & TPM_CHIP_FLAG_TPM2)
+- tpm2_shutdown(chip, TPM2_SU_STATE);
+- else
+- rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
+-
+- tpm_put_ops(chip);
++ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
++ tpm2_shutdown(chip, TPM2_SU_STATE);
++ goto suspended;
+ }
+
++ rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
++
+ suspended:
+ chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
++ tpm_put_ops(chip);
+
++out:
+ if (rc)
+ dev_err(dev, "Ignoring error %d while suspending\n", rc);
+ return 0;
+@@ -462,11 +468,18 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
+ if (!chip)
+ return -ENODEV;
+
++ /* Give back zero bytes, as TPM chip has not yet fully resumed: */
++ if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) {
++ rc = 0;
++ goto out;
++ }
++
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ rc = tpm2_get_random(chip, out, max);
+ else
+ rc = tpm1_get_random(chip, out, max);
+
++out:
+ tpm_put_ops(chip);
+ return rc;
+ }
+diff --git a/drivers/clk/clk-apple-nco.c b/drivers/clk/clk-apple-nco.c
+index 39472a51530a34..457a48d4894128 100644
+--- a/drivers/clk/clk-apple-nco.c
++++ b/drivers/clk/clk-apple-nco.c
+@@ -297,6 +297,9 @@ static int applnco_probe(struct platform_device *pdev)
+ memset(&init, 0, sizeof(init));
+ init.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "%s-%d", np->name, i);
++ if (!init.name)
++ return -ENOMEM;
++
+ init.ops = &applnco_ops;
+ init.parent_data = &pdata;
+ init.num_parents = 1;
+diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
+index bf4d8ddc93aea1..934e53a96dddac 100644
+--- a/drivers/clk/clk-axi-clkgen.c
++++ b/drivers/clk/clk-axi-clkgen.c
+@@ -7,6 +7,7 @@
+ */
+
+ #include <linux/platform_device.h>
++#include <linux/clk.h>
+ #include <linux/clk-provider.h>
+ #include <linux/slab.h>
+ #include <linux/io.h>
+@@ -512,6 +513,7 @@ static int axi_clkgen_probe(struct platform_device *pdev)
+ struct clk_init_data init;
+ const char *parent_names[2];
+ const char *clk_name;
++ struct clk *axi_clk;
+ unsigned int i;
+ int ret;
+
+@@ -528,8 +530,24 @@ static int axi_clkgen_probe(struct platform_device *pdev)
+ return PTR_ERR(axi_clkgen->base);
+
+ init.num_parents = of_clk_get_parent_count(pdev->dev.of_node);
+- if (init.num_parents < 1 || init.num_parents > 2)
+- return -EINVAL;
++
++ axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
++ if (!IS_ERR(axi_clk)) {
++ if (init.num_parents < 2 || init.num_parents > 3)
++ return -EINVAL;
++
++ init.num_parents -= 1;
++ } else {
++ /*
++ * Legacy... So that old DTs which do not have clock-names still
++ * work. In this case we don't explicitly enable the AXI bus
++ * clock.
++ */
++ if (PTR_ERR(axi_clk) != -ENOENT)
++ return PTR_ERR(axi_clk);
++ if (init.num_parents < 1 || init.num_parents > 2)
++ return -EINVAL;
++ }
+
+ for (i = 0; i < init.num_parents; i++) {
+ parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i);
+diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
+index 1becba2b62d0be..b12b00a2f07fab 100644
+--- a/drivers/clk/imx/clk-fracn-gppll.c
++++ b/drivers/clk/imx/clk-fracn-gppll.c
+@@ -252,9 +252,11 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
+ pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
+ FIELD_PREP(PLL_MFI_MASK, rate->mfi);
+ writel_relaxed(pll_div, pll->base + PLL_DIV);
++ readl(pll->base + PLL_DIV);
+ if (pll->flags & CLK_FRACN_GPPLL_FRACN) {
+ writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
+ writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
++ readl(pll->base + PLL_NUMERATOR);
+ }
+
+ /* Wait for 5us according to fracn mode pll doc */
+@@ -263,6 +265,7 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
+ /* Enable Powerup */
+ tmp |= POWERUP_MASK;
+ writel_relaxed(tmp, pll->base + PLL_CTRL);
++ readl(pll->base + PLL_CTRL);
+
+ /* Wait Lock */
+ ret = clk_fracn_gppll_wait_lock(pll);
+@@ -300,14 +303,15 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw)
+
+ val |= POWERUP_MASK;
+ writel_relaxed(val, pll->base + PLL_CTRL);
+-
+- val |= CLKMUX_EN;
+- writel_relaxed(val, pll->base + PLL_CTRL);
++ readl(pll->base + PLL_CTRL);
+
+ ret = clk_fracn_gppll_wait_lock(pll);
+ if (ret)
+ return ret;
+
++ val |= CLKMUX_EN;
++ writel_relaxed(val, pll->base + PLL_CTRL);
++
+ val &= ~CLKMUX_BYPASS;
+ writel_relaxed(val, pll->base + PLL_CTRL);
+
+diff --git a/drivers/clk/imx/clk-imx8-acm.c b/drivers/clk/imx/clk-imx8-acm.c
+index 1c95ae905eec82..b9ddb74b86f7a3 100644
+--- a/drivers/clk/imx/clk-imx8-acm.c
++++ b/drivers/clk/imx/clk-imx8-acm.c
+@@ -289,9 +289,9 @@ static int clk_imx_acm_attach_pm_domains(struct device *dev,
+ DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+- if (IS_ERR(dev_pm->pd_dev_link[i])) {
++ if (!dev_pm->pd_dev_link[i]) {
+ dev_pm_domain_detach(dev_pm->pd_dev[i], false);
+- ret = PTR_ERR(dev_pm->pd_dev_link[i]);
++ ret = -EINVAL;
+ goto detach_pm;
+ }
+ }
+diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c
+index dd5abd09f3e206..620afdf8dc03e9 100644
+--- a/drivers/clk/imx/clk-lpcg-scu.c
++++ b/drivers/clk/imx/clk-lpcg-scu.c
+@@ -6,10 +6,12 @@
+
+ #include <linux/bits.h>
+ #include <linux/clk-provider.h>
++#include <linux/delay.h>
+ #include <linux/err.h>
+ #include <linux/io.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
++#include <linux/units.h>
+
+ #include "clk-scu.h"
+
+@@ -41,6 +43,29 @@ struct clk_lpcg_scu {
+
+ #define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw)
+
++/* e10858 -LPCG clock gating register synchronization errata */
++static void lpcg_e10858_writel(unsigned long rate, void __iomem *reg, u32 val)
++{
++ writel(val, reg);
++
++ if (rate >= 24 * HZ_PER_MHZ || rate == 0) {
++ /*
++ * The time taken to access the LPCG registers from the AP core
++ * through the interconnect is longer than the minimum delay
++ * of 4 clock cycles required by the errata.
++ * Adding a readl will provide sufficient delay to prevent
++ * back-to-back writes.
++ */
++ readl(reg);
++ } else {
++ /*
++ * For clocks running below 24MHz, wait a minimum of
++ * 4 clock cycles.
++ */
++ ndelay(4 * (DIV_ROUND_UP(1000 * HZ_PER_MHZ, rate)));
++ }
++}
++
+ static int clk_lpcg_scu_enable(struct clk_hw *hw)
+ {
+ struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw);
+@@ -57,7 +82,8 @@ static int clk_lpcg_scu_enable(struct clk_hw *hw)
+ val |= CLK_GATE_SCU_LPCG_HW_SEL;
+
+ reg |= val << clk->bit_idx;
+- writel(reg, clk->reg);
++
++ lpcg_e10858_writel(clk_hw_get_rate(hw), clk->reg, reg);
+
+ spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
+
+@@ -74,7 +100,7 @@ static void clk_lpcg_scu_disable(struct clk_hw *hw)
+
+ reg = readl_relaxed(clk->reg);
+ reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx);
+- writel(reg, clk->reg);
++ lpcg_e10858_writel(clk_hw_get_rate(hw), clk->reg, reg);
+
+ spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
+ }
+@@ -145,13 +171,8 @@ static int __maybe_unused imx_clk_lpcg_scu_resume(struct device *dev)
+ {
+ struct clk_lpcg_scu *clk = dev_get_drvdata(dev);
+
+- /*
+- * FIXME: Sometimes writes don't work unless the CPU issues
+- * them twice
+- */
+-
+- writel(clk->state, clk->reg);
+ writel(clk->state, clk->reg);
++ lpcg_e10858_writel(0, clk->reg, clk->state);
+ dev_dbg(dev, "restore lpcg state 0x%x\n", clk->state);
+
+ return 0;
+diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
+index cd83c52e9952ab..564f549ec204f4 100644
+--- a/drivers/clk/imx/clk-scu.c
++++ b/drivers/clk/imx/clk-scu.c
+@@ -594,7 +594,7 @@ static int __maybe_unused imx_clk_scu_suspend(struct device *dev)
+ clk->rate = clk_scu_recalc_rate(&clk->hw, 0);
+ else
+ clk->rate = clk_hw_get_rate(&clk->hw);
+- clk->is_enabled = clk_hw_is_enabled(&clk->hw);
++ clk->is_enabled = clk_hw_is_prepared(&clk->hw);
+
+ if (clk->parent)
+ dev_dbg(dev, "save parent %s idx %u\n", clk_hw_get_name(clk->parent),
+diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
+index 48b42d11111cde..8ad02c1f035b30 100644
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -878,13 +878,6 @@ config COMMON_CLK_MT8195_APUSYS
+ help
+ This driver supports MediaTek MT8195 AI Processor Unit System clocks.
+
+-config COMMON_CLK_MT8195_AUDSYS
+- tristate "Clock driver for MediaTek MT8195 audsys"
+- depends on COMMON_CLK_MT8195
+- default COMMON_CLK_MT8195
+- help
+- This driver supports MediaTek MT8195 audsys clocks.
+-
+ config COMMON_CLK_MT8195_IMP_IIC_WRAP
+ tristate "Clock driver for MediaTek MT8195 imp_iic_wrap"
+ depends on COMMON_CLK_MT8195
+@@ -899,14 +892,6 @@ config COMMON_CLK_MT8195_MFGCFG
+ help
+ This driver supports MediaTek MT8195 mfgcfg clocks.
+
+-config COMMON_CLK_MT8195_MSDC
+- tristate "Clock driver for MediaTek MT8195 msdc"
+- depends on COMMON_CLK_MT8195
+- default COMMON_CLK_MT8195
+- help
+- This driver supports MediaTek MT8195 MMC and SD Controller's
+- msdc and msdc_top clocks.
+-
+ config COMMON_CLK_MT8195_SCP_ADSP
+ tristate "Clock driver for MediaTek MT8195 scp_adsp"
+ depends on COMMON_CLK_MT8195
+diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c
+index a39c4990b29dbf..7977b981b8e5fe 100644
+--- a/drivers/clk/qcom/gcc-qcs404.c
++++ b/drivers/clk/qcom/gcc-qcs404.c
+@@ -131,6 +131,7 @@ static struct clk_alpha_pll gpll1_out_main = {
+ /* 930MHz configuration */
+ static const struct alpha_pll_config gpll3_config = {
+ .l = 48,
++ .alpha_hi = 0x70,
+ .alpha = 0x0,
+ .alpha_en_mask = BIT(24),
+ .post_div_mask = 0xf << 8,
+diff --git a/drivers/clk/ralink/clk-mtmips.c b/drivers/clk/ralink/clk-mtmips.c
+index 50a443bf79ecd3..76285fbbdeaa2d 100644
+--- a/drivers/clk/ralink/clk-mtmips.c
++++ b/drivers/clk/ralink/clk-mtmips.c
+@@ -263,8 +263,9 @@ static int mtmips_register_pherip_clocks(struct device_node *np,
+ .rate = _rate \
+ }
+
+-static struct mtmips_clk_fixed rt305x_fixed_clocks[] = {
+- CLK_FIXED("xtal", NULL, 40000000)
++static struct mtmips_clk_fixed rt3883_fixed_clocks[] = {
++ CLK_FIXED("xtal", NULL, 40000000),
++ CLK_FIXED("periph", "xtal", 40000000)
+ };
+
+ static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {
+@@ -366,6 +367,12 @@ static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw)
+ return container_of(hw, struct mtmips_clk, hw);
+ }
+
++static unsigned long rt2880_xtal_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ return 40000000;
++}
++
+ static unsigned long rt5350_xtal_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+@@ -677,10 +684,12 @@ static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw,
+ }
+
+ static struct mtmips_clk rt2880_clks_base[] = {
++ { CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
+ { CLK_BASE("cpu", "xtal", rt2880_cpu_recalc_rate) }
+ };
+
+ static struct mtmips_clk rt305x_clks_base[] = {
++ { CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
+ { CLK_BASE("cpu", "xtal", rt305x_cpu_recalc_rate) }
+ };
+
+@@ -690,6 +699,7 @@ static struct mtmips_clk rt3352_clks_base[] = {
+ };
+
+ static struct mtmips_clk rt3883_clks_base[] = {
++ { CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
+ { CLK_BASE("cpu", "xtal", rt3883_cpu_recalc_rate) },
+ { CLK_BASE("bus", "cpu", rt3883_bus_recalc_rate) }
+ };
+@@ -746,8 +756,8 @@ static int mtmips_register_clocks(struct device_node *np,
+ static const struct mtmips_clk_data rt2880_clk_data = {
+ .clk_base = rt2880_clks_base,
+ .num_clk_base = ARRAY_SIZE(rt2880_clks_base),
+- .clk_fixed = rt305x_fixed_clocks,
+- .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
++ .clk_fixed = NULL,
++ .num_clk_fixed = 0,
+ .clk_factor = rt2880_factor_clocks,
+ .num_clk_factor = ARRAY_SIZE(rt2880_factor_clocks),
+ .clk_periph = rt2880_pherip_clks,
+@@ -757,8 +767,8 @@ static const struct mtmips_clk_data rt2880_clk_data = {
+ static const struct mtmips_clk_data rt305x_clk_data = {
+ .clk_base = rt305x_clks_base,
+ .num_clk_base = ARRAY_SIZE(rt305x_clks_base),
+- .clk_fixed = rt305x_fixed_clocks,
+- .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
++ .clk_fixed = NULL,
++ .num_clk_fixed = 0,
+ .clk_factor = rt305x_factor_clocks,
+ .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),
+ .clk_periph = rt305x_pherip_clks,
+@@ -779,8 +789,8 @@ static const struct mtmips_clk_data rt3352_clk_data = {
+ static const struct mtmips_clk_data rt3883_clk_data = {
+ .clk_base = rt3883_clks_base,
+ .num_clk_base = ARRAY_SIZE(rt3883_clks_base),
+- .clk_fixed = rt305x_fixed_clocks,
+- .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
++ .clk_fixed = rt3883_fixed_clocks,
++ .num_clk_fixed = ARRAY_SIZE(rt3883_fixed_clocks),
+ .clk_factor = NULL,
+ .num_clk_factor = 0,
+ .clk_periph = rt5350_pherip_clks,
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
+index 75f9eca020ce57..f8dbb092b9f1b2 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.c
++++ b/drivers/clk/renesas/rzg2l-cpg.c
+@@ -285,7 +285,7 @@ static unsigned long
+ rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
+ unsigned long rate)
+ {
+- unsigned long foutpostdiv_rate;
++ unsigned long foutpostdiv_rate, foutvco_rate;
+
+ params->pl5_intin = rate / MEGA;
+ params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA);
+@@ -294,10 +294,11 @@ rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
+ params->pl5_postdiv2 = 1;
+ params->pl5_spread = 0x16;
+
+- foutpostdiv_rate =
+- EXTAL_FREQ_IN_MEGA_HZ * MEGA / params->pl5_refdiv *
+- ((((params->pl5_intin << 24) + params->pl5_fracin)) >> 24) /
+- (params->pl5_postdiv1 * params->pl5_postdiv2);
++ foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA,
++ (params->pl5_intin << 24) + params->pl5_fracin),
++ params->pl5_refdiv) >> 24;
++ foutpostdiv_rate = DIV_ROUND_CLOSEST_ULL(foutvco_rate,
++ params->pl5_postdiv1 * params->pl5_postdiv2);
+
+ return foutpostdiv_rate;
+ }
+diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c
+index 48a8fb2c43b746..f95c3615ca7727 100644
+--- a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c
++++ b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c
+@@ -1371,7 +1371,7 @@ static int sun20i_d1_ccu_probe(struct platform_device *pdev)
+
+ /* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */
+ val = readl(reg + SUN20I_D1_PLL_AUDIO0_REG);
+- val &= ~BIT(1) | BIT(0);
++ val &= ~(BIT(1) | BIT(0));
+ writel(val, reg + SUN20I_D1_PLL_AUDIO0_REG);
+
+ /* Force fanout-27M factor N to 0. */
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index 0ba0dc4ecf0620..8208a3d895634b 100644
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -390,7 +390,8 @@ config ARM_GT_INITIAL_PRESCALER_VAL
+ This affects CPU_FREQ max delta from the initial frequency.
+
+ config ARM_TIMER_SP804
+- bool "Support for Dual Timer SP804 module" if COMPILE_TEST
++ bool "Support for Dual Timer SP804 module"
++ depends on ARM || ARM64 || COMPILE_TEST
+ depends on GENERIC_SCHED_CLOCK && HAVE_CLK
+ select CLKSRC_MMIO
+ select TIMER_OF if OF
+diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c
+index c2dcd8d68e4587..d1c144d6f328cf 100644
+--- a/drivers/clocksource/timer-ti-dm-systimer.c
++++ b/drivers/clocksource/timer-ti-dm-systimer.c
+@@ -686,9 +686,9 @@ subsys_initcall(dmtimer_percpu_timer_startup);
+
+ static int __init dmtimer_percpu_quirk_init(struct device_node *np, u32 pa)
+ {
+- struct device_node *arm_timer;
++ struct device_node *arm_timer __free(device_node) =
++ of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
+
+- arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
+ if (of_device_is_available(arm_timer)) {
+ pr_warn_once("ARM architected timer wrap issue i940 detected\n");
+ return 0;
+diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c
+index 1548dea15df140..81763e3f948467 100644
+--- a/drivers/comedi/comedi_fops.c
++++ b/drivers/comedi/comedi_fops.c
+@@ -2407,6 +2407,18 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
+
+ start += PAGE_SIZE;
+ }
++
++#ifdef CONFIG_MMU
++ /*
++ * Leaving behind a partial mapping of a buffer we're about to
++ * drop is unsafe, see remap_pfn_range_notrack().
++ * We need to zap the range here ourselves instead of relying
++ * on the automatic zapping in remap_pfn_range() because we call
++ * remap_pfn_range() in a loop.
++ */
++ if (retval)
++ zap_vma_ptes(vma, vma->vm_start, size);
++#endif
+ }
+
+ if (retval == 0) {
+diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
+index 6206d2dc3d4709..36d7f0d05b5f2f 100644
+--- a/drivers/counter/stm32-timer-cnt.c
++++ b/drivers/counter/stm32-timer-cnt.c
+@@ -195,11 +195,17 @@ static int stm32_count_enable_write(struct counter_device *counter,
+ {
+ struct stm32_timer_cnt *const priv = counter_priv(counter);
+ u32 cr1;
++ int ret;
+
+ if (enable) {
+ regmap_read(priv->regmap, TIM_CR1, &cr1);
+- if (!(cr1 & TIM_CR1_CEN))
+- clk_enable(priv->clk);
++ if (!(cr1 & TIM_CR1_CEN)) {
++ ret = clk_enable(priv->clk);
++ if (ret) {
++ dev_err(counter->parent, "Cannot enable clock %d\n", ret);
++ return ret;
++ }
++ }
+
+ regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
+ TIM_CR1_CEN);
+@@ -383,7 +389,11 @@ static int __maybe_unused stm32_timer_cnt_resume(struct device *dev)
+ return ret;
+
+ if (priv->enabled) {
+- clk_enable(priv->clk);
++ ret = clk_enable(priv->clk);
++ if (ret) {
++ dev_err(dev, "Cannot enable clock %d\n", ret);
++ return ret;
++ }
+
+ /* Restore registers that may have been lost */
+ regmap_write(priv->regmap, TIM_SMCR, priv->bak.smcr);
+diff --git a/drivers/counter/ti-ecap-capture.c b/drivers/counter/ti-ecap-capture.c
+index fb1cb1774674a5..b84e368a413f58 100644
+--- a/drivers/counter/ti-ecap-capture.c
++++ b/drivers/counter/ti-ecap-capture.c
+@@ -576,8 +576,13 @@ static int ecap_cnt_resume(struct device *dev)
+ {
+ struct counter_device *counter_dev = dev_get_drvdata(dev);
+ struct ecap_cnt_dev *ecap_dev = counter_priv(counter_dev);
++ int ret;
+
+- clk_enable(ecap_dev->clk);
++ ret = clk_enable(ecap_dev->clk);
++ if (ret) {
++ dev_err(dev, "Cannot enable clock %d\n", ret);
++ return ret;
++ }
+
+ ecap_cnt_capture_set_evmode(counter_dev, ecap_dev->pm_ctx.ev_mode);
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 8c16d67b98bfe4..cdead37d0823ad 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -1383,7 +1383,7 @@ static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
+ value = READ_ONCE(cpudata->cppc_req_cached);
+
+ if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
+- min_perf = max_perf;
++ min_perf = min(cpudata->nominal_perf, max_perf);
+
+ /* Initial min/max values for CPPC Performance Controls Register */
+ value &= ~AMD_CPPC_MIN_PERF(~0L);
+diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
+index 15f1d41920a339..c8447ecad797e7 100644
+--- a/drivers/cpufreq/cppc_cpufreq.c
++++ b/drivers/cpufreq/cppc_cpufreq.c
+@@ -118,6 +118,9 @@ static void cppc_scale_freq_workfn(struct kthread_work *work)
+
+ perf = cppc_perf_from_fbctrs(cpu_data, &cppc_fi->prev_perf_fb_ctrs,
+ &fb_ctrs);
++ if (!perf)
++ return;
++
+ cppc_fi->prev_perf_fb_ctrs = fb_ctrs;
+
+ perf <<= SCHED_CAPACITY_SHIFT;
+@@ -425,6 +428,9 @@ static int cppc_get_cpu_power(struct device *cpu_dev,
+ struct cppc_cpudata *cpu_data;
+
+ policy = cpufreq_cpu_get_raw(cpu_dev->id);
++ if (!policy)
++ return -EINVAL;
++
+ cpu_data = policy->driver_data;
+ perf_caps = &cpu_data->perf_caps;
+ max_cap = arch_scale_cpu_capacity(cpu_dev->id);
+@@ -492,6 +498,9 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz,
+ int step;
+
+ policy = cpufreq_cpu_get_raw(cpu_dev->id);
++ if (!policy)
++ return -EINVAL;
++
+ cpu_data = policy->driver_data;
+ perf_caps = &cpu_data->perf_caps;
+ max_cap = arch_scale_cpu_capacity(cpu_dev->id);
+@@ -730,13 +739,31 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data,
+ delta_delivered = get_delta(fb_ctrs_t1->delivered,
+ fb_ctrs_t0->delivered);
+
+- /* Check to avoid divide-by zero and invalid delivered_perf */
++ /*
++ * Avoid divide-by zero and unchanged feedback counters.
++ * Leave it for callers to handle.
++ */
+ if (!delta_reference || !delta_delivered)
+- return cpu_data->perf_ctrls.desired_perf;
++ return 0;
+
+ return (reference_perf * delta_delivered) / delta_reference;
+ }
+
++static int cppc_get_perf_ctrs_sample(int cpu,
++ struct cppc_perf_fb_ctrs *fb_ctrs_t0,
++ struct cppc_perf_fb_ctrs *fb_ctrs_t1)
++{
++ int ret;
++
++ ret = cppc_get_perf_ctrs(cpu, fb_ctrs_t0);
++ if (ret)
++ return ret;
++
++ udelay(2); /* 2usec delay between sampling */
++
++ return cppc_get_perf_ctrs(cpu, fb_ctrs_t1);
++}
++
+ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
+ {
+ struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0};
+@@ -752,18 +779,32 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
+
+ cpufreq_cpu_put(policy);
+
+- ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0);
+- if (ret)
+- return 0;
+-
+- udelay(2); /* 2usec delay between sampling */
+-
+- ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1);
+- if (ret)
+- return 0;
++ ret = cppc_get_perf_ctrs_sample(cpu, &fb_ctrs_t0, &fb_ctrs_t1);
++ if (ret) {
++ if (ret == -EFAULT)
++ /* Any of the associated CPPC regs is 0. */
++ goto out_invalid_counters;
++ else
++ return 0;
++ }
+
+ delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0,
+ &fb_ctrs_t1);
++ if (!delivered_perf)
++ goto out_invalid_counters;
++
++ return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
++
++out_invalid_counters:
++ /*
++ * Feedback counters could be unchanged or 0 when a cpu enters a
++ * low-power idle state, e.g. clock-gated or power-gated.
++ * Use desired perf for reflecting frequency. Get the latest register
++ * value first as some platforms may update the actual delivered perf
++ * there; if failed, resort to the cached desired perf.
++ */
++ if (cppc_get_desired_perf(cpu, &delivered_perf))
++ delivered_perf = cpu_data->perf_ctrls.desired_perf;
+
+ return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
+ }
+diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c
+index afc59b292153d3..63cae4037deb13 100644
+--- a/drivers/cpufreq/loongson2_cpufreq.c
++++ b/drivers/cpufreq/loongson2_cpufreq.c
+@@ -154,7 +154,9 @@ static int __init cpufreq_init(void)
+
+ ret = cpufreq_register_driver(&loongson2_cpufreq_driver);
+
+- if (!ret && !nowait) {
++ if (ret) {
++ platform_driver_unregister(&platform_driver);
++ } else if (!nowait) {
+ saved_cpu_wait = cpu_wait;
+ cpu_wait = loongson2_cpu_wait;
+ }
+diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
+index 8d097dcddda47d..55353fe7b9e744 100644
+--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
++++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
+@@ -62,7 +62,7 @@ mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *uW,
+
+ policy = cpufreq_cpu_get_raw(cpu_dev->id);
+ if (!policy)
+- return 0;
++ return -EINVAL;
+
+ data = policy->driver_data;
+
+diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c
+index 689be70d69c18b..1d1ff3b1b0d5a7 100644
+--- a/drivers/crypto/bcm/cipher.c
++++ b/drivers/crypto/bcm/cipher.c
+@@ -2415,6 +2415,7 @@ static int ahash_hmac_setkey(struct crypto_ahash *ahash, const u8 *key,
+
+ static int ahash_hmac_init(struct ahash_request *req)
+ {
++ int ret;
+ struct iproc_reqctx_s *rctx = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct iproc_ctx_s *ctx = crypto_ahash_ctx(tfm);
+@@ -2424,7 +2425,9 @@ static int ahash_hmac_init(struct ahash_request *req)
+ flow_log("ahash_hmac_init()\n");
+
+ /* init the context as a hash */
+- ahash_init(req);
++ ret = ahash_init(req);
++ if (ret)
++ return ret;
+
+ if (!spu_no_incr_hash(ctx)) {
+ /* SPU-M can do incr hashing but needs sw for outer HMAC */
+diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c
+index 887a5f2fb9279b..cb001aa1de6618 100644
+--- a/drivers/crypto/caam/caampkc.c
++++ b/drivers/crypto/caam/caampkc.c
+@@ -984,7 +984,7 @@ static int caam_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+ return -ENOMEM;
+ }
+
+-static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
++static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+ struct rsa_key *raw_key)
+ {
+ struct caam_rsa_key *rsa_key = &ctx->key;
+@@ -994,7 +994,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+
+ rsa_key->p = caam_read_raw_data(raw_key->p, &p_sz);
+ if (!rsa_key->p)
+- return;
++ return -ENOMEM;
+ rsa_key->p_sz = p_sz;
+
+ rsa_key->q = caam_read_raw_data(raw_key->q, &q_sz);
+@@ -1029,7 +1029,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+
+ rsa_key->priv_form = FORM3;
+
+- return;
++ return 0;
+
+ free_dq:
+ kfree_sensitive(rsa_key->dq);
+@@ -1043,6 +1043,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+ kfree_sensitive(rsa_key->q);
+ free_p:
+ kfree_sensitive(rsa_key->p);
++ return -ENOMEM;
+ }
+
+ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+@@ -1088,7 +1089,9 @@ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+ rsa_key->e_sz = raw_key.e_sz;
+ rsa_key->n_sz = raw_key.n_sz;
+
+- caam_rsa_set_priv_key_form(ctx, &raw_key);
++ ret = caam_rsa_set_priv_key_form(ctx, &raw_key);
++ if (ret)
++ goto err;
+
+ return 0;
+
+diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c
+index 46a083849a8ee6..7a3a104557f035 100644
+--- a/drivers/crypto/caam/qi.c
++++ b/drivers/crypto/caam/qi.c
+@@ -772,7 +772,7 @@ int caam_qi_init(struct platform_device *caam_pdev)
+
+ caam_debugfs_qi_init(ctrlpriv);
+
+- err = devm_add_action_or_reset(qidev, caam_qi_shutdown, ctrlpriv);
++ err = devm_add_action_or_reset(qidev, caam_qi_shutdown, qidev);
+ if (err)
+ return err;
+
+diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c
+index 6872ac3440010f..54de869e5374c2 100644
+--- a/drivers/crypto/cavium/cpt/cptpf_main.c
++++ b/drivers/crypto/cavium/cpt/cptpf_main.c
+@@ -44,7 +44,7 @@ static void cpt_disable_cores(struct cpt_device *cpt, u64 coremask,
+ dev_err(dev, "Cores still busy %llx", coremask);
+ grp = cpt_read_csr64(cpt->reg_base,
+ CPTX_PF_EXEC_BUSY(0));
+- if (timeout--)
++ if (!timeout--)
+ break;
+
+ udelay(CSR_DELAY);
+@@ -302,6 +302,8 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)
+
+ ret = do_cpt_init(cpt, mcode);
+ if (ret) {
++ dma_free_coherent(&cpt->pdev->dev, mcode->code_size,
++ mcode->code, mcode->phys_base);
+ dev_err(dev, "do_cpt_init failed with ret: %d\n", ret);
+ goto fw_release;
+ }
+@@ -394,7 +396,7 @@ static void cpt_disable_all_cores(struct cpt_device *cpt)
+ dev_err(dev, "Cores still busy");
+ grp = cpt_read_csr64(cpt->reg_base,
+ CPTX_PF_EXEC_BUSY(0));
+- if (timeout--)
++ if (!timeout--)
+ break;
+
+ udelay(CSR_DELAY);
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
+index 3463f5ee83c0df..762a2a54ca8219 100644
+--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
+@@ -1280,11 +1280,15 @@ static u32 hpre_get_hw_err_status(struct hisi_qm *qm)
+
+ static void hpre_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
+ {
+- u32 nfe;
+-
+ writel(err_sts, qm->io_base + HPRE_HAC_SOURCE_INT);
+- nfe = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
+- writel(nfe, qm->io_base + HPRE_RAS_NFE_ENB);
++}
++
++static void hpre_disable_error_report(struct hisi_qm *qm, u32 err_type)
++{
++ u32 nfe_mask;
++
++ nfe_mask = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
++ writel(nfe_mask & (~err_type), qm->io_base + HPRE_RAS_NFE_ENB);
+ }
+
+ static void hpre_open_axi_master_ooo(struct hisi_qm *qm)
+@@ -1298,6 +1302,27 @@ static void hpre_open_axi_master_ooo(struct hisi_qm *qm)
+ qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
+ }
+
++static enum acc_err_result hpre_get_err_result(struct hisi_qm *qm)
++{
++ u32 err_status;
++
++ err_status = hpre_get_hw_err_status(qm);
++ if (err_status) {
++ if (err_status & qm->err_info.ecc_2bits_mask)
++ qm->err_status.is_dev_ecc_mbit = true;
++ hpre_log_hw_error(qm, err_status);
++
++ if (err_status & qm->err_info.dev_reset_mask) {
++ /* Disable the same error reporting until device is recovered. */
++ hpre_disable_error_report(qm, err_status);
++ return ACC_ERR_NEED_RESET;
++ }
++ hpre_clear_hw_err_status(qm, err_status);
++ }
++
++ return ACC_ERR_RECOVERED;
++}
++
+ static void hpre_err_info_init(struct hisi_qm *qm)
+ {
+ struct hisi_qm_err_info *err_info = &qm->err_info;
+@@ -1324,12 +1349,12 @@ static const struct hisi_qm_err_ini hpre_err_ini = {
+ .hw_err_disable = hpre_hw_error_disable,
+ .get_dev_hw_err_status = hpre_get_hw_err_status,
+ .clear_dev_hw_err_status = hpre_clear_hw_err_status,
+- .log_dev_hw_err = hpre_log_hw_error,
+ .open_axi_master_ooo = hpre_open_axi_master_ooo,
+ .open_sva_prefetch = hpre_open_sva_prefetch,
+ .close_sva_prefetch = hpre_close_sva_prefetch,
+ .show_last_dfx_regs = hpre_show_last_dfx_regs,
+ .err_info_init = hpre_err_info_init,
++ .get_err_result = hpre_get_err_result,
+ };
+
+ static int hpre_pf_probe_init(struct hpre *hpre)
+diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
+index 1b00edbbfe26a9..7921409791fb03 100644
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -272,12 +272,6 @@ enum vft_type {
+ SHAPER_VFT,
+ };
+
+-enum acc_err_result {
+- ACC_ERR_NONE,
+- ACC_ERR_NEED_RESET,
+- ACC_ERR_RECOVERED,
+-};
+-
+ enum qm_alg_type {
+ ALG_TYPE_0,
+ ALG_TYPE_1,
+@@ -1489,22 +1483,25 @@ static void qm_log_hw_error(struct hisi_qm *qm, u32 error_status)
+
+ static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
+ {
+- u32 error_status, tmp;
+-
+- /* read err sts */
+- tmp = readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
+- error_status = qm->error_mask & tmp;
++ u32 error_status;
+
+- if (error_status) {
++ error_status = qm_get_hw_error_status(qm);
++ if (error_status & qm->error_mask) {
+ if (error_status & QM_ECC_MBIT)
+ qm->err_status.is_qm_ecc_mbit = true;
+
+ qm_log_hw_error(qm, error_status);
+- if (error_status & qm->err_info.qm_reset_mask)
++ if (error_status & qm->err_info.qm_reset_mask) {
++ /* Disable the same error reporting until device is recovered. */
++ writel(qm->err_info.nfe & (~error_status),
++ qm->io_base + QM_RAS_NFE_ENABLE);
+ return ACC_ERR_NEED_RESET;
++ }
+
++ /* Clear error source if not need reset. */
+ writel(error_status, qm->io_base + QM_ABNORMAL_INT_SOURCE);
+ writel(qm->err_info.nfe, qm->io_base + QM_RAS_NFE_ENABLE);
++ writel(qm->err_info.ce, qm->io_base + QM_RAS_CE_ENABLE);
+ }
+
+ return ACC_ERR_RECOVERED;
+@@ -3957,30 +3954,12 @@ EXPORT_SYMBOL_GPL(hisi_qm_sriov_configure);
+
+ static enum acc_err_result qm_dev_err_handle(struct hisi_qm *qm)
+ {
+- u32 err_sts;
+-
+- if (!qm->err_ini->get_dev_hw_err_status) {
+- dev_err(&qm->pdev->dev, "Device doesn't support get hw error status!\n");
++ if (!qm->err_ini->get_err_result) {
++ dev_err(&qm->pdev->dev, "Device doesn't support reset!\n");
+ return ACC_ERR_NONE;
+ }
+
+- /* get device hardware error status */
+- err_sts = qm->err_ini->get_dev_hw_err_status(qm);
+- if (err_sts) {
+- if (err_sts & qm->err_info.ecc_2bits_mask)
+- qm->err_status.is_dev_ecc_mbit = true;
+-
+- if (qm->err_ini->log_dev_hw_err)
+- qm->err_ini->log_dev_hw_err(qm, err_sts);
+-
+- if (err_sts & qm->err_info.dev_reset_mask)
+- return ACC_ERR_NEED_RESET;
+-
+- if (qm->err_ini->clear_dev_hw_err_status)
+- qm->err_ini->clear_dev_hw_err_status(qm, err_sts);
+- }
+-
+- return ACC_ERR_RECOVERED;
++ return qm->err_ini->get_err_result(qm);
+ }
+
+ static enum acc_err_result qm_process_dev_error(struct hisi_qm *qm)
+diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
+index cf7b6a37e7df7a..6aaaaf784ddc03 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_main.c
++++ b/drivers/crypto/hisilicon/sec2/sec_main.c
+@@ -1006,11 +1006,15 @@ static u32 sec_get_hw_err_status(struct hisi_qm *qm)
+
+ static void sec_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
+ {
+- u32 nfe;
+-
+ writel(err_sts, qm->io_base + SEC_CORE_INT_SOURCE);
+- nfe = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_NFE_MASK_CAP, qm->cap_ver);
+- writel(nfe, qm->io_base + SEC_RAS_NFE_REG);
++}
++
++static void sec_disable_error_report(struct hisi_qm *qm, u32 err_type)
++{
++ u32 nfe_mask;
++
++ nfe_mask = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_NFE_MASK_CAP, qm->cap_ver);
++ writel(nfe_mask & (~err_type), qm->io_base + SEC_RAS_NFE_REG);
+ }
+
+ static void sec_open_axi_master_ooo(struct hisi_qm *qm)
+@@ -1022,6 +1026,27 @@ static void sec_open_axi_master_ooo(struct hisi_qm *qm)
+ writel(val | SEC_AXI_SHUTDOWN_ENABLE, qm->io_base + SEC_CONTROL_REG);
+ }
+
++static enum acc_err_result sec_get_err_result(struct hisi_qm *qm)
++{
++ u32 err_status;
++
++ err_status = sec_get_hw_err_status(qm);
++ if (err_status) {
++ if (err_status & qm->err_info.ecc_2bits_mask)
++ qm->err_status.is_dev_ecc_mbit = true;
++ sec_log_hw_error(qm, err_status);
++
++ if (err_status & qm->err_info.dev_reset_mask) {
++ /* Disable the same error reporting until device is recovered. */
++ sec_disable_error_report(qm, err_status);
++ return ACC_ERR_NEED_RESET;
++ }
++ sec_clear_hw_err_status(qm, err_status);
++ }
++
++ return ACC_ERR_RECOVERED;
++}
++
+ static void sec_err_info_init(struct hisi_qm *qm)
+ {
+ struct hisi_qm_err_info *err_info = &qm->err_info;
+@@ -1048,12 +1073,12 @@ static const struct hisi_qm_err_ini sec_err_ini = {
+ .hw_err_disable = sec_hw_error_disable,
+ .get_dev_hw_err_status = sec_get_hw_err_status,
+ .clear_dev_hw_err_status = sec_clear_hw_err_status,
+- .log_dev_hw_err = sec_log_hw_error,
+ .open_axi_master_ooo = sec_open_axi_master_ooo,
+ .open_sva_prefetch = sec_open_sva_prefetch,
+ .close_sva_prefetch = sec_close_sva_prefetch,
+ .show_last_dfx_regs = sec_show_last_dfx_regs,
+ .err_info_init = sec_err_info_init,
++ .get_err_result = sec_get_err_result,
+ };
+
+ static int sec_pf_probe_init(struct sec_dev *sec)
+diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
+index 9d47b3675da7d4..66e553115adfd5 100644
+--- a/drivers/crypto/hisilicon/zip/zip_main.c
++++ b/drivers/crypto/hisilicon/zip/zip_main.c
+@@ -1068,11 +1068,15 @@ static u32 hisi_zip_get_hw_err_status(struct hisi_qm *qm)
+
+ static void hisi_zip_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
+ {
+- u32 nfe;
+-
+ writel(err_sts, qm->io_base + HZIP_CORE_INT_SOURCE);
+- nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
+- writel(nfe, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
++}
++
++static void hisi_zip_disable_error_report(struct hisi_qm *qm, u32 err_type)
++{
++ u32 nfe_mask;
++
++ nfe_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
++ writel(nfe_mask & (~err_type), qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
+ }
+
+ static void hisi_zip_open_axi_master_ooo(struct hisi_qm *qm)
+@@ -1102,6 +1106,27 @@ static void hisi_zip_close_axi_master_ooo(struct hisi_qm *qm)
+ qm->io_base + HZIP_CORE_INT_SET);
+ }
+
++static enum acc_err_result hisi_zip_get_err_result(struct hisi_qm *qm)
++{
++ u32 err_status;
++
++ err_status = hisi_zip_get_hw_err_status(qm);
++ if (err_status) {
++ if (err_status & qm->err_info.ecc_2bits_mask)
++ qm->err_status.is_dev_ecc_mbit = true;
++ hisi_zip_log_hw_error(qm, err_status);
++
++ if (err_status & qm->err_info.dev_reset_mask) {
++ /* Disable the same error reporting until device is recovered. */
++ hisi_zip_disable_error_report(qm, err_status);
++ return ACC_ERR_NEED_RESET;
++ }
++ hisi_zip_clear_hw_err_status(qm, err_status);
++ }
++
++ return ACC_ERR_RECOVERED;
++}
++
+ static void hisi_zip_err_info_init(struct hisi_qm *qm)
+ {
+ struct hisi_qm_err_info *err_info = &qm->err_info;
+@@ -1129,13 +1154,13 @@ static const struct hisi_qm_err_ini hisi_zip_err_ini = {
+ .hw_err_disable = hisi_zip_hw_error_disable,
+ .get_dev_hw_err_status = hisi_zip_get_hw_err_status,
+ .clear_dev_hw_err_status = hisi_zip_clear_hw_err_status,
+- .log_dev_hw_err = hisi_zip_log_hw_error,
+ .open_axi_master_ooo = hisi_zip_open_axi_master_ooo,
+ .close_axi_master_ooo = hisi_zip_close_axi_master_ooo,
+ .open_sva_prefetch = hisi_zip_open_sva_prefetch,
+ .close_sva_prefetch = hisi_zip_close_sva_prefetch,
+ .show_last_dfx_regs = hisi_zip_show_last_dfx_regs,
+ .err_info_init = hisi_zip_err_info_init,
++ .get_err_result = hisi_zip_get_err_result,
+ };
+
+ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index e17577b785c33a..f44c08f5f5ec4a 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -2093,7 +2093,7 @@ static int safexcel_xcbcmac_cra_init(struct crypto_tfm *tfm)
+
+ safexcel_ahash_cra_init(tfm);
+ ctx->aes = kmalloc(sizeof(*ctx->aes), GFP_KERNEL);
+- return PTR_ERR_OR_ZERO(ctx->aes);
++ return ctx->aes == NULL ? -ENOMEM : 0;
+ }
+
+ static void safexcel_xcbcmac_cra_exit(struct crypto_tfm *tfm)
+diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
+index 615af08832076a..403f0737144507 100644
+--- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
+@@ -473,7 +473,7 @@ static const char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num,
+ else
+ id = -EINVAL;
+
+- if (id < 0 || id > num_objs)
++ if (id < 0 || id >= num_objs)
+ return NULL;
+
+ return fw_objs[id];
+diff --git a/drivers/crypto/intel/qat/qat_common/adf_dbgfs.c b/drivers/crypto/intel/qat/qat_common/adf_dbgfs.c
+index 04845f8d72be6f..056fc59b5ae61d 100644
+--- a/drivers/crypto/intel/qat/qat_common/adf_dbgfs.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_dbgfs.c
+@@ -19,18 +19,13 @@
+ void adf_dbgfs_init(struct adf_accel_dev *accel_dev)
+ {
+ char name[ADF_DEVICE_NAME_LENGTH];
+- void *ret;
+
+ /* Create dev top level debugfs entry */
+ snprintf(name, sizeof(name), "%s%s_%s", ADF_DEVICE_NAME_PREFIX,
+ accel_dev->hw_device->dev_class->name,
+ pci_name(accel_dev->accel_pci_dev.pci_dev));
+
+- ret = debugfs_create_dir(name, NULL);
+- if (IS_ERR_OR_NULL(ret))
+- return;
+-
+- accel_dev->debugfs_dir = ret;
++ accel_dev->debugfs_dir = debugfs_create_dir(name, NULL);
+
+ adf_cfg_dev_dbgfs_add(accel_dev);
+ }
+@@ -56,9 +51,6 @@ EXPORT_SYMBOL_GPL(adf_dbgfs_exit);
+ */
+ void adf_dbgfs_add(struct adf_accel_dev *accel_dev)
+ {
+- if (!accel_dev->debugfs_dir)
+- return;
+-
+ if (!accel_dev->is_vf) {
+ adf_fw_counters_dbgfs_add(accel_dev);
+ adf_heartbeat_dbgfs_add(accel_dev);
+@@ -71,9 +63,6 @@ void adf_dbgfs_add(struct adf_accel_dev *accel_dev)
+ */
+ void adf_dbgfs_rm(struct adf_accel_dev *accel_dev)
+ {
+- if (!accel_dev->debugfs_dir)
+- return;
+-
+ if (!accel_dev->is_vf) {
+ adf_heartbeat_dbgfs_rm(accel_dev);
+ adf_fw_counters_dbgfs_rm(accel_dev);
+diff --git a/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c b/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c
+index da695669924674..dd9a31c20bc9c9 100644
+--- a/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c
+@@ -90,10 +90,6 @@ void adf_exit_arb(struct adf_accel_dev *accel_dev)
+
+ hw_data->get_arb_info(&info);
+
+- /* Reset arbiter configuration */
+- for (i = 0; i < ADF_ARB_NUM; i++)
+- WRITE_CSR_ARB_SARCONFIG(csr, arb_off, i, 0);
+-
+ /* Unmap worker threads to service arbiters */
+ for (i = 0; i < hw_data->num_engines; i++)
+ WRITE_CSR_ARB_WT2SAM(csr, arb_off, wt_off, i, 0);
+diff --git a/drivers/dax/pmem/Makefile b/drivers/dax/pmem/Makefile
+deleted file mode 100644
+index 191c31f0d4f008..00000000000000
+--- a/drivers/dax/pmem/Makefile
++++ /dev/null
+@@ -1,7 +0,0 @@
+-# SPDX-License-Identifier: GPL-2.0-only
+-obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
+-obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem_core.o
+-
+-dax_pmem-y := pmem.o
+-dax_pmem_core-y := core.o
+-dax_pmem_compat-y := compat.o
+diff --git a/drivers/dax/pmem/pmem.c b/drivers/dax/pmem/pmem.c
+deleted file mode 100644
+index dfe91a2990fec4..00000000000000
+--- a/drivers/dax/pmem/pmem.c
++++ /dev/null
+@@ -1,10 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */
+-#include <linux/percpu-refcount.h>
+-#include <linux/memremap.h>
+-#include <linux/module.h>
+-#include <linux/pfn_t.h>
+-#include <linux/nd.h>
+-#include "../bus.h"
+-
+-
+diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
+index c406459996489c..820c993c86592a 100644
+--- a/drivers/dma-buf/udmabuf.c
++++ b/drivers/dma-buf/udmabuf.c
+@@ -35,12 +35,13 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
+ struct vm_area_struct *vma = vmf->vma;
+ struct udmabuf *ubuf = vma->vm_private_data;
+ pgoff_t pgoff = vmf->pgoff;
++ unsigned long pfn;
+
+ if (pgoff >= ubuf->pagecount)
+ return VM_FAULT_SIGBUS;
+- vmf->page = ubuf->pages[pgoff];
+- get_page(vmf->page);
+- return 0;
++
++ pfn = page_to_pfn(ubuf->pages[pgoff]);
++ return vmf_insert_pfn(vma, vmf->address, pfn);
+ }
+
+ static const struct vm_operations_struct udmabuf_vm_ops = {
+@@ -56,6 +57,7 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
+
+ vma->vm_ops = &udmabuf_vm_ops;
+ vma->vm_private_data = ubuf;
++ vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+ return 0;
+ }
+
+diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
+index e4736eb37bfb33..0ef04898276824 100644
+--- a/drivers/edac/bluefield_edac.c
++++ b/drivers/edac/bluefield_edac.c
+@@ -180,7 +180,7 @@ static void bluefield_edac_check(struct mem_ctl_info *mci)
+ static void bluefield_edac_init_dimms(struct mem_ctl_info *mci)
+ {
+ struct bluefield_edac_priv *priv = mci->pvt_info;
+- int mem_ctrl_idx = mci->mc_idx;
++ u64 mem_ctrl_idx = mci->mc_idx;
+ struct dimm_info *dimm;
+ u64 smc_info, smc_arg;
+ int is_empty = 1, i;
+diff --git a/drivers/edac/fsl_ddr_edac.c b/drivers/edac/fsl_ddr_edac.c
+index b81757555a8a96..7809427c2dbeb1 100644
+--- a/drivers/edac/fsl_ddr_edac.c
++++ b/drivers/edac/fsl_ddr_edac.c
+@@ -328,21 +328,25 @@ static void fsl_mc_check(struct mem_ctl_info *mci)
+ * TODO: Add support for 32-bit wide buses
+ */
+ if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) {
++ u64 cap = (u64)cap_high << 32 | cap_low;
++ u32 s = syndrome;
++
+ sbe_ecc_decode(cap_high, cap_low, syndrome,
+ &bad_data_bit, &bad_ecc_bit);
+
+- if (bad_data_bit != -1)
+- fsl_mc_printk(mci, KERN_ERR,
+- "Faulty Data bit: %d\n", bad_data_bit);
+- if (bad_ecc_bit != -1)
+- fsl_mc_printk(mci, KERN_ERR,
+- "Faulty ECC bit: %d\n", bad_ecc_bit);
++ if (bad_data_bit >= 0) {
++ fsl_mc_printk(mci, KERN_ERR, "Faulty Data bit: %d\n", bad_data_bit);
++ cap ^= 1ULL << bad_data_bit;
++ }
++
++ if (bad_ecc_bit >= 0) {
++ fsl_mc_printk(mci, KERN_ERR, "Faulty ECC bit: %d\n", bad_ecc_bit);
++ s ^= 1 << bad_ecc_bit;
++ }
+
+ fsl_mc_printk(mci, KERN_ERR,
+ "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
+- cap_high ^ (1 << (bad_data_bit - 32)),
+- cap_low ^ (1 << bad_data_bit),
+- syndrome ^ (1 << bad_ecc_bit));
++ upper_32_bits(cap), lower_32_bits(cap), s);
+ }
+
+ fsl_mc_printk(mci, KERN_ERR,
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index 2b83d6de9352be..535f058b48eef5 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -1088,6 +1088,7 @@ static int __init i10nm_init(void)
+ return -ENODEV;
+
+ cfg = (struct res_config *)id->driver_data;
++ skx_set_res_cfg(cfg);
+ res_cfg = cfg;
+
+ rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
+diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c
+index a0edb61a5a01ac..0b408299699a8e 100644
+--- a/drivers/edac/igen6_edac.c
++++ b/drivers/edac/igen6_edac.c
+@@ -1075,6 +1075,7 @@ static int igen6_register_mci(int mc, u64 mchbar, struct pci_dev *pdev)
+ imc->mci = mci;
+ return 0;
+ fail3:
++ mci->pvt_info = NULL;
+ kfree(mci->ctl_name);
+ fail2:
+ edac_mc_free(mci);
+@@ -1099,6 +1100,7 @@ static void igen6_unregister_mcis(void)
+
+ edac_mc_del_mc(mci->pdev);
+ kfree(mci->ctl_name);
++ mci->pvt_info = NULL;
+ edac_mc_free(mci);
+ iounmap(imc->window);
+ }
+diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
+index 8d18099fd528cf..0b8aaf5f77d9f6 100644
+--- a/drivers/edac/skx_common.c
++++ b/drivers/edac/skx_common.c
+@@ -47,6 +47,7 @@ static skx_show_retry_log_f skx_show_retry_rd_err_log;
+ static u64 skx_tolm, skx_tohm;
+ static LIST_HEAD(dev_edac_list);
+ static bool skx_mem_cfg_2lm;
++static struct res_config *skx_res_cfg;
+
+ int skx_adxl_get(void)
+ {
+@@ -119,7 +120,7 @@ void skx_adxl_put(void)
+ }
+ EXPORT_SYMBOL_GPL(skx_adxl_put);
+
+-static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_mem)
++static bool skx_adxl_decode(struct decoded_addr *res, enum error_source err_src)
+ {
+ struct skx_dev *d;
+ int i, len = 0;
+@@ -135,8 +136,24 @@ static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_me
+ return false;
+ }
+
++ /*
++ * GNR with a Flat2LM memory configuration may mistakenly classify
++ * a near-memory error(DDR5) as a far-memory error(CXL), resulting
++ * in the incorrect selection of decoded ADXL components.
++ * To address this, prefetch the decoded far-memory controller ID
++ * and adjust the error source to near-memory if the far-memory
++ * controller ID is invalid.
++ */
++ if (skx_res_cfg && skx_res_cfg->type == GNR && err_src == ERR_SRC_2LM_FM) {
++ res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]];
++ if (res->imc == -1) {
++ err_src = ERR_SRC_2LM_NM;
++ edac_dbg(0, "Adjust the error source to near-memory.\n");
++ }
++ }
++
+ res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]];
+- if (error_in_1st_level_mem) {
++ if (err_src == ERR_SRC_2LM_NM) {
+ res->imc = (adxl_nm_bitmap & BIT_NM_MEMCTRL) ?
+ (int)adxl_values[component_indices[INDEX_NM_MEMCTRL]] : -1;
+ res->channel = (adxl_nm_bitmap & BIT_NM_CHANNEL) ?
+@@ -191,6 +208,12 @@ void skx_set_mem_cfg(bool mem_cfg_2lm)
+ }
+ EXPORT_SYMBOL_GPL(skx_set_mem_cfg);
+
++void skx_set_res_cfg(struct res_config *cfg)
++{
++ skx_res_cfg = cfg;
++}
++EXPORT_SYMBOL_GPL(skx_set_res_cfg);
++
+ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log)
+ {
+ driver_decode = decode;
+@@ -620,31 +643,27 @@ static void skx_mce_output_error(struct mem_ctl_info *mci,
+ optype, skx_msg);
+ }
+
+-static bool skx_error_in_1st_level_mem(const struct mce *m)
++static enum error_source skx_error_source(const struct mce *m)
+ {
+- u32 errcode;
++ u32 errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK;
+
+- if (!skx_mem_cfg_2lm)
+- return false;
+-
+- errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK;
+-
+- return errcode == MCACOD_EXT_MEM_ERR;
+-}
++ if (errcode != MCACOD_MEM_CTL_ERR && errcode != MCACOD_EXT_MEM_ERR)
++ return ERR_SRC_NOT_MEMORY;
+
+-static bool skx_error_in_mem(const struct mce *m)
+-{
+- u32 errcode;
++ if (!skx_mem_cfg_2lm)
++ return ERR_SRC_1LM;
+
+- errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK;
++ if (errcode == MCACOD_EXT_MEM_ERR)
++ return ERR_SRC_2LM_NM;
+
+- return (errcode == MCACOD_MEM_CTL_ERR || errcode == MCACOD_EXT_MEM_ERR);
++ return ERR_SRC_2LM_FM;
+ }
+
+ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
+ void *data)
+ {
+ struct mce *mce = (struct mce *)data;
++ enum error_source err_src;
+ struct decoded_addr res;
+ struct mem_ctl_info *mci;
+ char *type;
+@@ -652,8 +671,10 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
+ if (mce->kflags & MCE_HANDLED_CEC)
+ return NOTIFY_DONE;
+
++ err_src = skx_error_source(mce);
++
+ /* Ignore unless this is memory related with an address */
+- if (!skx_error_in_mem(mce) || !(mce->status & MCI_STATUS_ADDRV))
++ if (err_src == ERR_SRC_NOT_MEMORY || !(mce->status & MCI_STATUS_ADDRV))
+ return NOTIFY_DONE;
+
+ memset(&res, 0, sizeof(res));
+@@ -667,7 +688,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
+ /* Try driver decoder first */
+ if (!(driver_decode && driver_decode(&res))) {
+ /* Then try firmware decoder (ACPI DSM methods) */
+- if (!(adxl_component_count && skx_adxl_decode(&res, skx_error_in_1st_level_mem(mce))))
++ if (!(adxl_component_count && skx_adxl_decode(&res, err_src)))
+ return NOTIFY_DONE;
+ }
+
+diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h
+index 11faf1db4fa482..e7f18ada166814 100644
+--- a/drivers/edac/skx_common.h
++++ b/drivers/edac/skx_common.h
+@@ -147,6 +147,13 @@ enum {
+ INDEX_MAX
+ };
+
++enum error_source {
++ ERR_SRC_1LM,
++ ERR_SRC_2LM_NM,
++ ERR_SRC_2LM_FM,
++ ERR_SRC_NOT_MEMORY,
++};
++
+ #define BIT_NM_MEMCTRL BIT_ULL(INDEX_NM_MEMCTRL)
+ #define BIT_NM_CHANNEL BIT_ULL(INDEX_NM_CHANNEL)
+ #define BIT_NM_DIMM BIT_ULL(INDEX_NM_DIMM)
+@@ -235,6 +242,7 @@ int skx_adxl_get(void);
+ void skx_adxl_put(void);
+ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
+ void skx_set_mem_cfg(bool mem_cfg_2lm);
++void skx_set_res_cfg(struct res_config *cfg);
+
+ int skx_get_src_id(struct skx_dev *d, int off, u8 *id);
+ int skx_get_node_id(struct skx_dev *d, u8 *id);
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index 00b165d1f502df..039f686f4580d1 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -163,6 +163,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
+ * used to initialize this channel
+ * @dev: Reference to device in the SCMI hierarchy corresponding to this
+ * channel
++ * @is_p2a: A flag to identify a channel as P2A (RX)
+ * @rx_timeout_ms: The configured RX timeout in milliseconds.
+ * @handle: Pointer to SCMI entity handle
+ * @no_completion_irq: Flag to indicate that this channel has no completion
+@@ -174,6 +175,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
+ struct scmi_chan_info {
+ int id;
+ struct device *dev;
++ bool is_p2a;
+ unsigned int rx_timeout_ms;
+ struct scmi_handle *handle;
+ bool no_completion_irq;
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 3962683e2af9d4..efa9698c876a09 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -855,6 +855,11 @@ static inline void scmi_xfer_command_release(struct scmi_info *info,
+ static inline void scmi_clear_channel(struct scmi_info *info,
+ struct scmi_chan_info *cinfo)
+ {
++ if (!cinfo->is_p2a) {
++ dev_warn(cinfo->dev, "Invalid clear on A2P channel !\n");
++ return;
++ }
++
+ if (info->desc->ops->clear_channel)
+ info->desc->ops->clear_channel(cinfo);
+ }
+@@ -2319,6 +2324,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
+ if (!cinfo)
+ return -ENOMEM;
+
++ cinfo->is_p2a = !tx;
+ cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
+
+ /* Create a unique name for this transport device */
+diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
+index 435d0e2658a42e..3de25e9d18ef84 100644
+--- a/drivers/firmware/arm_scpi.c
++++ b/drivers/firmware/arm_scpi.c
+@@ -627,6 +627,9 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
+ if (ret)
+ return ERR_PTR(ret);
+
++ if (!buf.opp_count)
++ return ERR_PTR(-ENOENT);
++
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
+index f9c1e8a2bd1d3e..ec01b7d3b6d4d5 100644
+--- a/drivers/firmware/efi/libstub/efi-stub.c
++++ b/drivers/firmware/efi/libstub/efi-stub.c
+@@ -129,7 +129,7 @@ efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr)
+
+ if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
+ IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
+- cmdline_size == 0) {
++ cmdline[0] == 0) {
+ status = efi_parse_options(CONFIG_CMDLINE);
+ if (status != EFI_SUCCESS) {
+ efi_err("Failed to parse options\n");
+@@ -149,7 +149,7 @@ efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr)
+ return EFI_SUCCESS;
+
+ fail_free_cmdline:
+- efi_bs_call(free_pool, cmdline_ptr);
++ efi_bs_call(free_pool, cmdline);
+ return status;
+ }
+
+diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c
+index e8d69bd548f3fe..9c3613e6af158f 100644
+--- a/drivers/firmware/efi/tpm.c
++++ b/drivers/firmware/efi/tpm.c
+@@ -40,7 +40,8 @@ int __init efi_tpm_eventlog_init(void)
+ {
+ struct linux_efi_tpm_eventlog *log_tbl;
+ struct efi_tcg2_final_events_table *final_tbl;
+- int tbl_size;
++ unsigned int tbl_size;
++ int final_tbl_size;
+ int ret = 0;
+
+ if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) {
+@@ -80,26 +81,26 @@ int __init efi_tpm_eventlog_init(void)
+ goto out;
+ }
+
+- tbl_size = 0;
++ final_tbl_size = 0;
+ if (final_tbl->nr_events != 0) {
+ void *events = (void *)efi.tpm_final_log
+ + sizeof(final_tbl->version)
+ + sizeof(final_tbl->nr_events);
+
+- tbl_size = tpm2_calc_event_log_size(events,
+- final_tbl->nr_events,
+- log_tbl->log);
++ final_tbl_size = tpm2_calc_event_log_size(events,
++ final_tbl->nr_events,
++ log_tbl->log);
+ }
+
+- if (tbl_size < 0) {
++ if (final_tbl_size < 0) {
+ pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n");
+ ret = -EINVAL;
+ goto out_calc;
+ }
+
+ memblock_reserve(efi.tpm_final_log,
+- tbl_size + sizeof(*final_tbl));
+- efi_tpm_final_log_size = tbl_size;
++ final_tbl_size + sizeof(*final_tbl));
++ efi_tpm_final_log_size = final_tbl_size;
+
+ out_calc:
+ early_memunmap(final_tbl, sizeof(*final_tbl));
+diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
+index 96ea1fa76d351f..854d488e025e96 100644
+--- a/drivers/firmware/google/gsmi.c
++++ b/drivers/firmware/google/gsmi.c
+@@ -918,7 +918,8 @@ static __init int gsmi_init(void)
+ gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
+ if (IS_ERR(gsmi_dev.pdev)) {
+ printk(KERN_ERR "gsmi: unable to register platform device\n");
+- return PTR_ERR(gsmi_dev.pdev);
++ ret = PTR_ERR(gsmi_dev.pdev);
++ goto out_unregister;
+ }
+
+ /* SMI access needs to be serialized */
+@@ -1056,10 +1057,11 @@ static __init int gsmi_init(void)
+ gsmi_buf_free(gsmi_dev.name_buf);
+ kmem_cache_destroy(gsmi_dev.mem_pool);
+ platform_device_unregister(gsmi_dev.pdev);
+- pr_info("gsmi: failed to load: %d\n", ret);
++out_unregister:
+ #ifdef CONFIG_PM
+ platform_driver_unregister(&gsmi_driver_info);
+ #endif
++ pr_info("gsmi: failed to load: %d\n", ret);
+ return ret;
+ }
+
+diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c
+index 5170fe7599cdf8..d5909a4f0433c1 100644
+--- a/drivers/gpio/gpio-exar.c
++++ b/drivers/gpio/gpio-exar.c
+@@ -99,11 +99,13 @@ static void exar_set_value(struct gpio_chip *chip, unsigned int offset,
+ struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
+ unsigned int addr = exar_offset_to_lvl_addr(exar_gpio, offset);
+ unsigned int bit = exar_offset_to_bit(exar_gpio, offset);
++ unsigned int bit_value = value ? BIT(bit) : 0;
+
+- if (value)
+- regmap_set_bits(exar_gpio->regmap, addr, BIT(bit));
+- else
+- regmap_clear_bits(exar_gpio->regmap, addr, BIT(bit));
++ /*
++ * regmap_write_bits() forces value to be written when an external
++ * pull up/down might otherwise indicate value was already set.
++ */
++ regmap_write_bits(exar_gpio->regmap, addr, BIT(bit), bit_value);
+ }
+
+ static int exar_direction_output(struct gpio_chip *chip, unsigned int offset,
+diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c
+index 2de61337ad3b54..d7230fd83f5d68 100644
+--- a/drivers/gpio/gpio-zevio.c
++++ b/drivers/gpio/gpio-zevio.c
+@@ -11,6 +11,7 @@
+ #include <linux/io.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/platform_device.h>
++#include <linux/property.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+
+@@ -169,6 +170,7 @@ static const struct gpio_chip zevio_gpio_chip = {
+ /* Initialization */
+ static int zevio_gpio_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
+ struct zevio_gpio *controller;
+ int status, i;
+
+@@ -180,6 +182,10 @@ static int zevio_gpio_probe(struct platform_device *pdev)
+ controller->chip = zevio_gpio_chip;
+ controller->chip.parent = &pdev->dev;
+
++ controller->chip.label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", dev_fwnode(dev));
++ if (!controller->chip.label)
++ return -ENOMEM;
++
+ controller->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(controller->regs))
+ return dev_err_probe(&pdev->dev, PTR_ERR(controller->regs),
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 9c99d69b4b083e..cd2d99e00b5d9d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4020,8 +4020,8 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
+ int idx;
+ bool px;
+
+- amdgpu_fence_driver_sw_fini(adev);
+ amdgpu_device_ip_fini(adev);
++ amdgpu_fence_driver_sw_fini(adev);
+ amdgpu_ucode_release(&adev->firmware.gpu_info_fw);
+ adev->accel_working = false;
+ dma_fence_put(rcu_dereference_protected(adev->gang_submit, true));
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+index 88a3aa36b41d77..8e91355ad42cc5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+@@ -214,15 +214,15 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev)
+
+ drm_sched_entity_destroy(&adev->vce.entity);
+
+- amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr,
+- (void **)&adev->vce.cpu_addr);
+-
+ for (i = 0; i < adev->vce.num_rings; i++)
+ amdgpu_ring_fini(&adev->vce.ring[i]);
+
+ amdgpu_ucode_release(&adev->vce.fw);
+ mutex_destroy(&adev->vce.idle_mutex);
+
++ amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr,
++ (void **)&adev->vce.cpu_addr);
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+index 1bea629c49ca02..68d13c4fac8f4f 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+@@ -123,7 +123,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_node *dev,
+
+ memset(kq->pq_kernel_addr, 0, queue_size);
+ memset(kq->rptr_kernel, 0, sizeof(*kq->rptr_kernel));
+- memset(kq->wptr_kernel, 0, sizeof(*kq->wptr_kernel));
++ memset(kq->wptr_kernel, 0, dev->kfd->device_info.doorbell_size);
+
+ prop.queue_size = queue_size;
+ prop.is_interop = false;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index 6c90231e0aec2b..fd640a061c96a8 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -312,8 +312,8 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
+ attr_sdma);
+ struct kfd_sdma_activity_handler_workarea sdma_activity_work_handler;
+
+- INIT_WORK(&sdma_activity_work_handler.sdma_activity_work,
+- kfd_sdma_activity_worker);
++ INIT_WORK_ONSTACK(&sdma_activity_work_handler.sdma_activity_work,
++ kfd_sdma_activity_worker);
+
+ sdma_activity_work_handler.pdd = pdd;
+ sdma_activity_work_handler.sdma_activity_counter = 0;
+@@ -321,6 +321,7 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
+ schedule_work(&sdma_activity_work_handler.sdma_activity_work);
+
+ flush_work(&sdma_activity_work_handler.sdma_activity_work);
++ destroy_work_on_stack(&sdma_activity_work_handler.sdma_activity_work);
+
+ return snprintf(buffer, PAGE_SIZE, "%llu\n",
+ (sdma_activity_work_handler.sdma_activity_counter)/
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+index d390e3d62e56e3..9ec9792f115a8a 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -179,6 +179,8 @@ amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector)
+ dc_sink_release(dc_sink);
+ aconnector->dc_sink = NULL;
+ aconnector->edid = NULL;
++ aconnector->dsc_aux = NULL;
++ port->passthrough_aux = NULL;
+ }
+
+ aconnector->mst_status = MST_STATUS_DEFAULT;
+@@ -487,6 +489,8 @@ dm_dp_mst_detect(struct drm_connector *connector,
+ dc_sink_release(aconnector->dc_sink);
+ aconnector->dc_sink = NULL;
+ aconnector->edid = NULL;
++ aconnector->dsc_aux = NULL;
++ port->passthrough_aux = NULL;
+
+ amdgpu_dm_set_mst_status(&aconnector->mst_status,
+ MST_REMOTE_EDID | MST_ALLOCATE_NEW_PAYLOAD | MST_CLEAR_ALLOCATED_PAYLOAD,
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+index 3271c8c7905ddc..4e036356b6a89a 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+@@ -560,11 +560,19 @@ void dcn3_clk_mgr_construct(
+ dce_clock_read_ss_info(clk_mgr);
+
+ clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL);
++ if (!clk_mgr->base.bw_params) {
++ BREAK_TO_DEBUGGER();
++ return;
++ }
+
+ /* need physical address of table to give to PMFW */
+ clk_mgr->wm_range_table = dm_helpers_allocate_gpu_mem(clk_mgr->base.ctx,
+ DC_MEM_ALLOC_TYPE_GART, sizeof(WatermarksExternal_t),
+ &clk_mgr->wm_range_table_addr);
++ if (!clk_mgr->wm_range_table) {
++ BREAK_TO_DEBUGGER();
++ return;
++ }
+ }
+
+ void dcn3_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr)
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+index 2428a4763b85f6..1c5ae4d62e37b7 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+@@ -1022,11 +1022,19 @@ void dcn32_clk_mgr_construct(
+ clk_mgr->smu_present = false;
+
+ clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL);
++ if (!clk_mgr->base.bw_params) {
++ BREAK_TO_DEBUGGER();
++ return;
++ }
+
+ /* need physical address of table to give to PMFW */
+ clk_mgr->wm_range_table = dm_helpers_allocate_gpu_mem(clk_mgr->base.ctx,
+ DC_MEM_ALLOC_TYPE_GART, sizeof(WatermarksExternal_t),
+ &clk_mgr->wm_range_table_addr);
++ if (!clk_mgr->wm_range_table) {
++ BREAK_TO_DEBUGGER();
++ return;
++ }
+ }
+
+ void dcn32_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr)
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+index f99ec1b0efaffb..2eae1fd95fd06b 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+@@ -727,6 +727,9 @@ void hwss_setup_dpp(union block_sequence_params *params)
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
+ struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+
++ if (!plane_state)
++ return;
++
+ if (dpp && dpp->funcs->dpp_setup) {
+ // program the input csc
+ dpp->funcs->dpp_setup(dpp,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+index 12af2859002f72..a825fd6c7fa666 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -880,7 +880,8 @@ bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+ /*
+ * if above if is not executed then 'params' equal to 0 and set in bypass
+ */
+- mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
++ if (mpc->funcs->set_output_gamma)
++ mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+
+ return true;
+ }
+@@ -1732,17 +1733,26 @@ static void dcn20_program_pipe(
+ dc->res_pool->hubbub->funcs->program_det_size(
+ dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->det_buffer_size_kb);
+
+- if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
++ if (pipe_ctx->update_flags.raw ||
++ (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.raw) ||
++ pipe_ctx->stream->update_flags.raw)
+ dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
+
+- if (pipe_ctx->update_flags.bits.enable
+- || pipe_ctx->plane_state->update_flags.bits.hdr_mult)
++ if (pipe_ctx->update_flags.bits.enable ||
++ (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.hdr_mult))
+ hws->funcs.set_hdr_multiplier(pipe_ctx);
+
+- if (pipe_ctx->update_flags.bits.enable ||
+- pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+- pipe_ctx->plane_state->update_flags.bits.gamma_change ||
+- pipe_ctx->plane_state->update_flags.bits.lut_3d)
++ if ((pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.hdr_mult) ||
++ pipe_ctx->update_flags.bits.enable)
++ hws->funcs.set_hdr_multiplier(pipe_ctx);
++
++ if ((pipe_ctx->plane_state &&
++ pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change) ||
++ (pipe_ctx->plane_state &&
++ pipe_ctx->plane_state->update_flags.bits.gamma_change) ||
++ (pipe_ctx->plane_state &&
++ pipe_ctx->plane_state->update_flags.bits.lut_3d) ||
++ pipe_ctx->update_flags.bits.enable)
+ hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
+
+ /* dcn10_translate_regamma_to_hw_format takes 750us to finish
+@@ -1752,7 +1762,8 @@ static void dcn20_program_pipe(
+ if (pipe_ctx->update_flags.bits.enable ||
+ pipe_ctx->update_flags.bits.plane_changed ||
+ pipe_ctx->stream->update_flags.bits.out_tf ||
+- pipe_ctx->plane_state->update_flags.bits.output_tf_change)
++ (pipe_ctx->plane_state &&
++ pipe_ctx->plane_state->update_flags.bits.output_tf_change))
+ hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
+
+ /* If the pipe has been enabled or has a different opp, we
+@@ -1776,7 +1787,7 @@ static void dcn20_program_pipe(
+ }
+
+ /* Set ABM pipe after other pipe configurations done */
+- if (pipe_ctx->plane_state->visible) {
++ if ((pipe_ctx->plane_state && pipe_ctx->plane_state->visible)) {
+ if (pipe_ctx->stream_res.abm) {
+ dc->hwss.set_pipe(pipe_ctx);
+ pipe_ctx->stream_res.abm->funcs->set_abm_level(pipe_ctx->stream_res.abm,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index ba4a1e7f196d10..b8653bdfc40fbd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -440,7 +440,7 @@ void dcn30_init_hw(struct dc *dc)
+ int edp_num;
+ uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+
+- if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
++ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks)
+ dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+ // Initialize the dccg
+@@ -599,11 +599,12 @@ void dcn30_init_hw(struct dc *dc)
+ if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
+ dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
+
+- if (dc->clk_mgr->funcs->notify_wm_ranges)
++ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges)
+ dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+ //if softmax is enabled then hardmax will be set by a different call
+- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
++ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk &&
++ !dc->clk_mgr->dc_mode_softmax_enabled)
+ dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+ if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+index 88c0b24a32497d..de83acd12250d8 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+@@ -2045,6 +2045,9 @@ bool dcn30_validate_bandwidth(struct dc *dc,
+
+ BW_VAL_TRACE_COUNT();
+
++ if (!pipes)
++ goto validate_fail;
++
+ DC_FP_START();
+ out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
+ DC_FP_END();
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+index 82de4fe2637fc1..84e3df49be2f8c 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+@@ -1308,6 +1308,8 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create(
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
++ if (!hpo_dp_enc31)
++ return NULL; /* out of memory */
+
+ hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
+ &hpo_dp_link_enc_regs[inst],
+@@ -1764,6 +1766,9 @@ bool dcn31_validate_bandwidth(struct dc *dc,
+
+ BW_VAL_TRACE_COUNT();
+
++ if (!pipes)
++ goto validate_fail;
++
+ DC_FP_START();
+ out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
+ DC_FP_END();
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index 3e65e683db0acf..6e52851bc0316b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -1381,6 +1381,8 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create(
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
++ if (!hpo_dp_enc31)
++ return NULL; /* out of memory */
+
+ hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
+ &hpo_dp_link_enc_regs[inst],
+@@ -1741,6 +1743,9 @@ bool dcn314_validate_bandwidth(struct dc *dc,
+
+ BW_VAL_TRACE_COUNT();
+
++ if (!pipes)
++ goto validate_fail;
++
+ if (filter_modes_for_single_channel_workaround(dc, context))
+ goto validate_fail;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
+index 127487ea3d7dc3..3f3b555b4523a2 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
+@@ -1308,6 +1308,8 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create(
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
++ if (!hpo_dp_enc31)
++ return NULL; /* out of memory */
+
+ hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
+ &hpo_dp_link_enc_regs[inst],
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
+index 5fe2c61527dfad..37b7973fc9494a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
+@@ -1305,6 +1305,8 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create(
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
++ if (!hpo_dp_enc31)
++ return NULL; /* out of memory */
+
+ hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
+ &hpo_dp_link_enc_regs[inst],
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index 650e1598bddcb1..1a24fc8b536740 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -587,7 +587,9 @@ bool dcn32_set_output_transfer_func(struct dc *dc,
+ }
+ }
+
+- mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
++ if (mpc->funcs->set_output_gamma)
++ mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
++
+ return ret;
+ }
+
+@@ -771,7 +773,7 @@ void dcn32_init_hw(struct dc *dc)
+ int edp_num;
+ uint32_t backlight = MAX_BACKLIGHT_LEVEL;
+
+- if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
++ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks)
+ dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
+
+ // Initialize the dccg
+@@ -948,10 +950,11 @@ void dcn32_init_hw(struct dc *dc)
+ if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
+ dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
+
+- if (dc->clk_mgr->funcs->notify_wm_ranges)
++ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges)
+ dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
++ if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk &&
++ !dc->clk_mgr->dc_mode_softmax_enabled)
+ dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+ if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+index f9d601c8c72176..f98f35ac68c01a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+@@ -1299,6 +1299,8 @@ static struct hpo_dp_link_encoder *dcn32_hpo_dp_link_encoder_create(
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
++ if (!hpo_dp_enc31)
++ return NULL; /* out of memory */
+
+ #undef REG_STRUCT
+ #define REG_STRUCT hpo_dp_link_enc_regs
+@@ -1786,6 +1788,9 @@ void dcn32_add_phantom_pipes(struct dc *dc, struct dc_state *context,
+ // be a valid candidate for SubVP (i.e. has a plane, stream, doesn't
+ // already have phantom pipe assigned, etc.) by previous checks.
+ phantom_stream = dcn32_enable_phantom_stream(dc, context, pipes, pipe_cnt, index);
++ if (!phantom_stream)
++ return;
++
+ dcn32_enable_phantom_plane(dc, context, phantom_stream, index);
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+@@ -1842,6 +1847,9 @@ bool dcn32_validate_bandwidth(struct dc *dc,
+
+ BW_VAL_TRACE_COUNT();
+
++ if (!pipes)
++ goto validate_fail;
++
+ DC_FP_START();
+ out = dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
+ DC_FP_END();
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+index aa4c64eec7b3d6..4289cd1643ece6 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+@@ -1285,6 +1285,8 @@ static struct hpo_dp_link_encoder *dcn321_hpo_dp_link_encoder_create(
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
++ if (!hpo_dp_enc31)
++ return NULL; /* out of memory */
+
+ #undef REG_STRUCT
+ #define REG_STRUCT hpo_dp_link_enc_regs
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+index 548cdef8a8ade2..543ce9a08cfd31 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+@@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
+
+ static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
+ {
+- unsigned int ret_val = 0;
++ unsigned int ret_val = 1;
+
+ if (source_format == dm_444_16) {
+ if (!is_chroma)
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+index 3d82cbef12740c..ac6357c089e701 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+@@ -932,8 +932,9 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)
+ * for VBLANK: (VACTIVE region of the SubVP pipe can fit the MALL prefetch, VBLANK frame time,
+ * and the max of (VBLANK blanking time, MALL region)).
+ */
+- if (stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 1000000 * 1000000 &&
+- subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion > 0)
++ if (drr_timing &&
++ stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 1000000 * 1000000 &&
++ subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion > 0)
+ schedulable = true;
+
+ return schedulable;
+@@ -995,7 +996,7 @@ static bool subvp_vblank_schedulable(struct dc *dc, struct dc_state *context)
+ if (!subvp_pipe && pipe->stream->mall_stream_config.type == SUBVP_MAIN)
+ subvp_pipe = pipe;
+ }
+- if (found) {
++ if (found && subvp_pipe) {
+ main_timing = &subvp_pipe->stream->timing;
+ phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing;
+ vblank_timing = &context->res_ctx.pipe_ctx[vblank_index].stream->timing;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+index 3df559c591f890..70df992f859d7b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+@@ -39,7 +39,7 @@
+
+ static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
+ {
+- unsigned int ret_val = 0;
++ unsigned int ret_val = 1;
+
+ if (source_format == dm_444_16) {
+ if (!is_chroma)
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+index 51ae41cb43ea0e..e1521d3a5e0ca1 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -1725,6 +1725,8 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu,
+ gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency;
+
+ gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK];
++ gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK];
++ gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK];
+ gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0];
+ gpu_metrics->current_dclk0 = metrics->CurrClock[PPCLK_DCLK_0];
+ gpu_metrics->current_vclk1 = metrics->CurrClock[PPCLK_VCLK_1];
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index c1191ef5e8e679..412c6575e87b74 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -2573,6 +2573,8 @@ static int __maybe_unused anx7625_runtime_pm_suspend(struct device *dev)
+ mutex_lock(&ctx->lock);
+
+ anx7625_stop_dp_work(ctx);
++ if (!ctx->pdata.panel_bridge)
++ anx7625_remove_edid(ctx);
+ anx7625_power_standby(ctx);
+
+ mutex_unlock(&ctx->lock);
+diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
+index 4ad527fe04f27e..93eb8fba23d428 100644
+--- a/drivers/gpu/drm/bridge/ite-it6505.c
++++ b/drivers/gpu/drm/bridge/ite-it6505.c
+@@ -3104,6 +3104,8 @@ static __maybe_unused int it6505_bridge_suspend(struct device *dev)
+ {
+ struct it6505 *it6505 = dev_get_drvdata(dev);
+
++ it6505_remove_edid(it6505);
++
+ return it6505_poweroff(it6505);
+ }
+
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index 7fd4a5fe03edf6..6a3f29390313b4 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -1579,6 +1579,13 @@ static struct edid *tc_get_edid(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+ {
+ struct tc_data *tc = bridge_to_tc(bridge);
++ int ret;
++
++ ret = tc_get_display_props(tc);
++ if (ret < 0) {
++ dev_err(tc->dev, "failed to read display props: %d\n", ret);
++ return 0;
++ }
+
+ return drm_get_edid(connector, &tc->aux.ddc);
+ }
+diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
+index 48af0e2960a226..1d22dba69b2753 100644
+--- a/drivers/gpu/drm/drm_file.c
++++ b/drivers/gpu/drm/drm_file.c
+@@ -149,7 +149,7 @@ bool drm_dev_needs_global_mutex(struct drm_device *dev)
+ */
+ struct drm_file *drm_file_alloc(struct drm_minor *minor)
+ {
+- static atomic64_t ident = ATOMIC_INIT(0);
++ static atomic64_t ident = ATOMIC64_INIT(0);
+ struct drm_device *dev = minor->dev;
+ struct drm_file *file;
+ int ret;
+diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
+index 8257f9d4f6190d..22a373eaffefd1 100644
+--- a/drivers/gpu/drm/drm_mm.c
++++ b/drivers/gpu/drm/drm_mm.c
+@@ -151,7 +151,7 @@ static void show_leaks(struct drm_mm *mm) { }
+
+ INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
+ u64, __subtree_last,
+- START, LAST, static inline, drm_mm_interval_tree)
++ START, LAST, static inline __maybe_unused, drm_mm_interval_tree)
+
+ struct drm_mm_node *
+ __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last)
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index 5b2506c65e9520..259a0c765bafbf 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -403,7 +403,6 @@ static const struct dmi_system_id orientation_data[] = {
+ }, { /* Lenovo Yoga Tab 3 X90F */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
+ },
+ .driver_data = (void *)&lcd1600x2560_rightside_up,
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+index 384df1659be60d..b13a17276d07cd 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+@@ -482,7 +482,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
+ } else {
+ CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
+ VIVS_GL_FLUSH_CACHE_DEPTH |
+- VIVS_GL_FLUSH_CACHE_COLOR);
++ VIVS_GL_FLUSH_CACHE_COLOR |
++ VIVS_GL_FLUSH_CACHE_SHADER_L1);
+ if (has_blt) {
+ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
+ CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+index f9bc837e22bddc..85d0695e94a5f8 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+@@ -527,6 +527,16 @@ static int etnaviv_bind(struct device *dev)
+ priv->num_gpus = 0;
+ priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
+
++ /*
++ * If the GPU is part of a system with DMA addressing limitations,
++ * request pages for our SHM backend buffers from the DMA32 zone to
++ * hopefully avoid performance killing SWIOTLB bounce buffering.
++ */
++ if (dma_addressing_limited(dev)) {
++ priv->shm_gfp_mask |= GFP_DMA32;
++ priv->shm_gfp_mask &= ~__GFP_HIGHMEM;
++ }
++
+ priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
+ if (IS_ERR(priv->cmdbuf_suballoc)) {
+ dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index 371e1f2733f6fb..ad543a7cbf073e 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -820,14 +820,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
+ if (ret)
+ goto fail;
+
+- /*
+- * If the GPU is part of a system with DMA addressing limitations,
+- * request pages for our SHM backend buffers from the DMA32 zone to
+- * hopefully avoid performance killing SWIOTLB bounce buffering.
+- */
+- if (dma_addressing_limited(gpu->dev))
+- priv->shm_gfp_mask |= GFP_DMA32;
+-
+ /* Create buffer: */
+ ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
+ PAGE_SIZE);
+@@ -1308,6 +1300,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
+ {
+ u32 val;
+
++ mutex_lock(&gpu->lock);
++
+ /* disable clock gating */
+ val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
+ val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
+@@ -1319,6 +1313,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
+ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
+
+ sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE);
++
++ mutex_unlock(&gpu->lock);
+ }
+
+ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
+@@ -1328,13 +1324,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
+ unsigned int i;
+ u32 val;
+
+- sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
+-
+- for (i = 0; i < submit->nr_pmrs; i++) {
+- const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
++ mutex_lock(&gpu->lock);
+
+- *pmr->bo_vma = pmr->sequence;
+- }
++ sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
+
+ /* disable debug register */
+ val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
+@@ -1345,6 +1337,14 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
+ val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
+ val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
+ gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
++
++ mutex_unlock(&gpu->lock);
++
++ for (i = 0; i < submit->nr_pmrs; i++) {
++ const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
++
++ *pmr->bo_vma = pmr->sequence;
++ }
+ }
+
+
+diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig
+index 5ca71ef8732590..c9ee98693b48a4 100644
+--- a/drivers/gpu/drm/fsl-dcu/Kconfig
++++ b/drivers/gpu/drm/fsl-dcu/Kconfig
+@@ -8,6 +8,7 @@ config DRM_FSL_DCU
+ select DRM_PANEL
+ select REGMAP_MMIO
+ select VIDEOMODE_HELPERS
++ select MFD_SYSCON if SOC_LS1021A
+ help
+ Choose this option if you have an Freescale DCU chipset.
+ If M is selected the module will be called fsl-dcu-drm.
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+index a395f93449f368..a23f3f5c5530b9 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+@@ -100,6 +100,7 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev)
+ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
+ {
+ struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
++ struct regmap *scfg;
+ int ret;
+
+ ret = fsl_dcu_drm_modeset_init(fsl_dev);
+@@ -108,6 +109,20 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
+ return ret;
+ }
+
++ scfg = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg");
++ if (PTR_ERR(scfg) != -ENODEV) {
++ /*
++ * For simplicity, enable the PIXCLK unconditionally,
++ * resulting in increased power consumption. Disabling
++ * the clock in PM or on unload could be implemented as
++ * a future improvement.
++ */
++ ret = regmap_update_bits(scfg, SCFG_PIXCLKCR, SCFG_PIXCLKCR_PXCEN,
++ SCFG_PIXCLKCR_PXCEN);
++ if (ret < 0)
++ return dev_err_probe(dev->dev, ret, "failed to enable pixclk\n");
++ }
++
+ ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+ if (ret < 0) {
+ dev_err(dev->dev, "failed to initialize vblank\n");
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+index e2049a0e8a92a5..566396013c04a5 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+@@ -160,6 +160,9 @@
+ #define FSL_DCU_ARGB4444 12
+ #define FSL_DCU_YUV422 14
+
++#define SCFG_PIXCLKCR 0x28
++#define SCFG_PIXCLKCR_PXCEN BIT(31)
++
+ #define VF610_LAYER_REG_NUM 9
+ #define LS1021A_LAYER_REG_NUM 10
+
+diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c
+index 31267c00782fc1..af91e45b5d13b7 100644
+--- a/drivers/gpu/drm/imx/dcss/dcss-crtc.c
++++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c
+@@ -206,15 +206,13 @@ int dcss_crtc_init(struct dcss_crtc *crtc, struct drm_device *drm)
+ if (crtc->irq < 0)
+ return crtc->irq;
+
+- ret = request_irq(crtc->irq, dcss_crtc_irq_handler,
+- 0, "dcss_drm", crtc);
++ ret = request_irq(crtc->irq, dcss_crtc_irq_handler, IRQF_NO_AUTOEN,
++ "dcss_drm", crtc);
+ if (ret) {
+ dev_err(dcss->dev, "irq request failed with %d.\n", ret);
+ return ret;
+ }
+
+- disable_irq(crtc->irq);
+-
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
+index 89585b31b985e1..5f423a2e0ede36 100644
+--- a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
++++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
+@@ -410,14 +410,12 @@ static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
+ }
+
+ ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
+- ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
+- "imx_drm", ipu_crtc);
++ ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler,
++ IRQF_NO_AUTOEN, "imx_drm", ipu_crtc);
+ if (ret < 0) {
+ dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
+ return ret;
+ }
+- /* Only enable IRQ when we actually need it to trigger work. */
+- disable_irq(ipu_crtc->irq);
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index ffe016d6cbcfe0..600f4ccc90d378 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -378,8 +378,10 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
+ if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound)
+ cnt++;
+
+- if (cnt == MAX_CRTC)
++ if (cnt == MAX_CRTC) {
++ of_node_put(node);
+ break;
++ }
+ }
+
+ if (drm_priv->data->mmsys_dev_num == cnt) {
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+index 7923129363b0ae..c9edaa6d763697 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+@@ -1432,15 +1432,13 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
+
+ irq = platform_get_irq_byname(pdev, name);
+
+- ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu);
++ ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, name, gmu);
+ if (ret) {
+ DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n",
+ name, ret);
+ return ret;
+ }
+
+- disable_irq(irq);
+-
+ return irq;
+ }
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
+index 43c47a19cd94f5..a857ce8e385fc0 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
+@@ -157,18 +157,6 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
+ .sblk = &msm8998_lm_sblk,
+ .lm_pair = LM_5,
+ .pingpong = PINGPONG_2,
+- }, {
+- .name = "lm_3", .id = LM_3,
+- .base = 0x47000, .len = 0x320,
+- .features = MIXER_MSM8998_MASK,
+- .sblk = &msm8998_lm_sblk,
+- .pingpong = PINGPONG_NONE,
+- }, {
+- .name = "lm_4", .id = LM_4,
+- .base = 0x48000, .len = 0x320,
+- .features = MIXER_MSM8998_MASK,
+- .sblk = &msm8998_lm_sblk,
+- .pingpong = PINGPONG_NONE,
+ }, {
+ .name = "lm_5", .id = LM_5,
+ .base = 0x49000, .len = 0x320,
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
+index 88a5177dfdb73e..3749c014870d36 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
+@@ -156,19 +156,6 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
+ .lm_pair = LM_5,
+ .pingpong = PINGPONG_2,
+ .dspp = DSPP_2,
+- }, {
+- .name = "lm_3", .id = LM_3,
+- .base = 0x0, .len = 0x320,
+- .features = MIXER_SDM845_MASK,
+- .sblk = &sdm845_lm_sblk,
+- .pingpong = PINGPONG_NONE,
+- .dspp = DSPP_3,
+- }, {
+- .name = "lm_4", .id = LM_4,
+- .base = 0x0, .len = 0x320,
+- .features = MIXER_SDM845_MASK,
+- .sblk = &sdm845_lm_sblk,
+- .pingpong = PINGPONG_NONE,
+ }, {
+ .name = "lm_5", .id = LM_5,
+ .base = 0x49000, .len = 0x320,
+@@ -176,6 +163,7 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
+ .sblk = &sdm845_lm_sblk,
+ .lm_pair = LM_2,
+ .pingpong = PINGPONG_3,
++ .dspp = DSPP_3,
+ },
+ };
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+index 68fae048a9a837..260accc151d4b4 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+@@ -80,7 +80,7 @@ static u64 _dpu_core_perf_calc_clk(const struct dpu_perf_cfg *perf_cfg,
+
+ mode = &state->adjusted_mode;
+
+- crtc_clk = mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
++ crtc_clk = (u64)mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
+
+ drm_atomic_crtc_for_each_plane(plane, crtc) {
+ pstate = to_dpu_plane_state(plane->state);
+diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+index ea70c1c32d9401..6970b0f7f457c8 100644
+--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
++++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+@@ -140,6 +140,7 @@ void msm_devfreq_init(struct msm_gpu *gpu)
+ {
+ struct msm_gpu_devfreq *df = &gpu->devfreq;
+ struct msm_drm_private *priv = gpu->dev->dev_private;
++ int ret;
+
+ /* We need target support to do devfreq */
+ if (!gpu->funcs->gpu_busy)
+@@ -156,8 +157,12 @@ void msm_devfreq_init(struct msm_gpu *gpu)
+
+ mutex_init(&df->lock);
+
+- dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
+- DEV_PM_QOS_MIN_FREQUENCY, 0);
++ ret = dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
++ DEV_PM_QOS_MIN_FREQUENCY, 0);
++ if (ret < 0) {
++ DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize QoS\n");
++ return;
++ }
+
+ msm_devfreq_profile.initial_freq = gpu->fast_rate;
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+index 3648868bb9fc51..cd533d16b96639 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+@@ -443,6 +443,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch,
+ ret = gf100_grctx_generate(gr, chan, fifoch->inst);
+ if (ret) {
+ nvkm_error(&base->engine.subdev, "failed to construct context\n");
++ mutex_unlock(&gr->fecs.mutex);
+ return ret;
+ }
+ }
+diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
+index 050ca7eafac586..556e0f9026bedd 100644
+--- a/drivers/gpu/drm/omapdrm/dss/base.c
++++ b/drivers/gpu/drm/omapdrm/dss/base.c
+@@ -139,21 +139,13 @@ static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
+ }
+
+ int omapdss_device_connect(struct dss_device *dss,
+- struct omap_dss_device *src,
+ struct omap_dss_device *dst)
+ {
+- dev_dbg(&dss->pdev->dev, "connect(%s, %s)\n",
+- src ? dev_name(src->dev) : "NULL",
++ dev_dbg(&dss->pdev->dev, "connect(%s)\n",
+ dst ? dev_name(dst->dev) : "NULL");
+
+- if (!dst) {
+- /*
+- * The destination is NULL when the source is connected to a
+- * bridge instead of a DSS device. Stop here, we will attach
+- * the bridge later when we will have a DRM encoder.
+- */
+- return src && src->bridge ? 0 : -EINVAL;
+- }
++ if (!dst)
++ return -EINVAL;
+
+ if (omapdss_device_is_connected(dst))
+ return -EBUSY;
+@@ -163,19 +155,14 @@ int omapdss_device_connect(struct dss_device *dss,
+ return 0;
+ }
+
+-void omapdss_device_disconnect(struct omap_dss_device *src,
++void omapdss_device_disconnect(struct dss_device *dss,
+ struct omap_dss_device *dst)
+ {
+- struct dss_device *dss = src ? src->dss : dst->dss;
+-
+- dev_dbg(&dss->pdev->dev, "disconnect(%s, %s)\n",
+- src ? dev_name(src->dev) : "NULL",
++ dev_dbg(&dss->pdev->dev, "disconnect(%s)\n",
+ dst ? dev_name(dst->dev) : "NULL");
+
+- if (!dst) {
+- WARN_ON(!src->bridge);
++ if (WARN_ON(!dst))
+ return;
+- }
+
+ if (!dst->id && !omapdss_device_is_connected(dst)) {
+ WARN_ON(1);
+diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
+index 040d5a3e33d680..4c22c09c93d523 100644
+--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
++++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
+@@ -242,9 +242,8 @@ struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev);
+ void omapdss_device_put(struct omap_dss_device *dssdev);
+ struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node);
+ int omapdss_device_connect(struct dss_device *dss,
+- struct omap_dss_device *src,
+ struct omap_dss_device *dst);
+-void omapdss_device_disconnect(struct omap_dss_device *src,
++void omapdss_device_disconnect(struct dss_device *dss,
+ struct omap_dss_device *dst);
+
+ int omap_dss_get_num_overlay_managers(void);
+diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
+index 21996b713d1c3a..13790d3ac3b6a5 100644
+--- a/drivers/gpu/drm/omapdrm/omap_drv.c
++++ b/drivers/gpu/drm/omapdrm/omap_drv.c
+@@ -307,7 +307,7 @@ static void omap_disconnect_pipelines(struct drm_device *ddev)
+ for (i = 0; i < priv->num_pipes; i++) {
+ struct omap_drm_pipeline *pipe = &priv->pipes[i];
+
+- omapdss_device_disconnect(NULL, pipe->output);
++ omapdss_device_disconnect(priv->dss, pipe->output);
+
+ omapdss_device_put(pipe->output);
+ pipe->output = NULL;
+@@ -325,7 +325,7 @@ static int omap_connect_pipelines(struct drm_device *ddev)
+ int r;
+
+ for_each_dss_output(output) {
+- r = omapdss_device_connect(priv->dss, NULL, output);
++ r = omapdss_device_connect(priv->dss, output);
+ if (r == -EPROBE_DEFER) {
+ omapdss_device_put(output);
+ return r;
+diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
+index c48fa531ca321c..68117eed702bef 100644
+--- a/drivers/gpu/drm/omapdrm/omap_gem.c
++++ b/drivers/gpu/drm/omapdrm/omap_gem.c
+@@ -1395,8 +1395,6 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
+
+ omap_obj = to_omap_bo(obj);
+
+- mutex_lock(&omap_obj->lock);
+-
+ omap_obj->sgt = sgt;
+
+ if (sgt->orig_nents == 1) {
+@@ -1411,21 +1409,17 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
+ pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
+ if (!pages) {
+ omap_gem_free_object(obj);
+- obj = ERR_PTR(-ENOMEM);
+- goto done;
++ return ERR_PTR(-ENOMEM);
+ }
+
+ omap_obj->pages = pages;
+ ret = drm_prime_sg_to_page_array(sgt, pages, npages);
+ if (ret) {
+ omap_gem_free_object(obj);
+- obj = ERR_PTR(-ENOMEM);
+- goto done;
++ return ERR_PTR(-ENOMEM);
+ }
+ }
+
+-done:
+- mutex_unlock(&omap_obj->lock);
+ return obj;
+ }
+
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c
+index c067ff550692ad..164c4690cacaf9 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
+@@ -157,7 +157,6 @@ static void panfrost_gpu_init_quirks(struct panfrost_device *pfdev)
+ struct panfrost_model {
+ const char *name;
+ u32 id;
+- u32 id_mask;
+ u64 features;
+ u64 issues;
+ struct {
+diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
+index 4aca09cab4b8cd..7ea76fdd714a9d 100644
+--- a/drivers/gpu/drm/radeon/atombios_encoders.c
++++ b/drivers/gpu/drm/radeon/atombios_encoders.c
+@@ -2178,7 +2178,7 @@ int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder, int fe_idx)
+ void
+ radeon_atom_encoder_init(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_encoder *encoder;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
+index 10be30366c2bf8..341441b241835f 100644
+--- a/drivers/gpu/drm/radeon/cik.c
++++ b/drivers/gpu/drm/radeon/cik.c
+@@ -7585,7 +7585,7 @@ int cik_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[0]) {
+- drm_handle_vblank(rdev->ddev, 0);
++ drm_handle_vblank(rdev_to_drm(rdev), 0);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -7615,7 +7615,7 @@ int cik_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[1]) {
+- drm_handle_vblank(rdev->ddev, 1);
++ drm_handle_vblank(rdev_to_drm(rdev), 1);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -7645,7 +7645,7 @@ int cik_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[2]) {
+- drm_handle_vblank(rdev->ddev, 2);
++ drm_handle_vblank(rdev_to_drm(rdev), 2);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -7675,7 +7675,7 @@ int cik_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[3]) {
+- drm_handle_vblank(rdev->ddev, 3);
++ drm_handle_vblank(rdev_to_drm(rdev), 3);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -7705,7 +7705,7 @@ int cik_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[4]) {
+- drm_handle_vblank(rdev->ddev, 4);
++ drm_handle_vblank(rdev_to_drm(rdev), 4);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -7735,7 +7735,7 @@ int cik_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[5]) {
+- drm_handle_vblank(rdev->ddev, 5);
++ drm_handle_vblank(rdev_to_drm(rdev), 5);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -8581,7 +8581,7 @@ int cik_init(struct radeon_device *rdev)
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+
+ /* Fence driver */
+ radeon_fence_driver_init(rdev);
+diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c
+index 4a1d5447eac17b..4419a0e85f69bf 100644
+--- a/drivers/gpu/drm/radeon/dce6_afmt.c
++++ b/drivers/gpu/drm/radeon/dce6_afmt.c
+@@ -90,7 +90,7 @@ struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev)
+ pin = &rdev->audio.pin[i];
+ pin_count = 0;
+
+- list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
++ list_for_each_entry(encoder, &rdev_to_drm(rdev)->mode_config.encoder_list, head) {
+ if (radeon_encoder_is_digital(encoder)) {
+ radeon_encoder = to_radeon_encoder(encoder);
+ dig = radeon_encoder->enc_priv;
+diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
+index f0ae087be914ee..a7f9fc2b523999 100644
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -1672,7 +1672,7 @@ void evergreen_pm_misc(struct radeon_device *rdev)
+ */
+ void evergreen_pm_prepare(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 tmp;
+@@ -1697,7 +1697,7 @@ void evergreen_pm_prepare(struct radeon_device *rdev)
+ */
+ void evergreen_pm_finish(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 tmp;
+@@ -1762,7 +1762,7 @@ void evergreen_hpd_set_polarity(struct radeon_device *rdev,
+ */
+ void evergreen_hpd_init(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned enabled = 0;
+ u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) |
+@@ -1803,7 +1803,7 @@ void evergreen_hpd_init(struct radeon_device *rdev)
+ */
+ void evergreen_hpd_fini(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned disabled = 0;
+
+@@ -4756,7 +4756,7 @@ int evergreen_irq_process(struct radeon_device *rdev)
+ event_name = "vblank";
+
+ if (rdev->irq.crtc_vblank_int[crtc_idx]) {
+- drm_handle_vblank(rdev->ddev, crtc_idx);
++ drm_handle_vblank(rdev_to_drm(rdev), crtc_idx);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -5214,7 +5214,7 @@ int evergreen_init(struct radeon_device *rdev)
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* Fence driver */
+ radeon_fence_driver_init(rdev);
+ /* initialize AGP */
+diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
+index 3e48cbb522a1ca..4cd89fd6e9a220 100644
+--- a/drivers/gpu/drm/radeon/ni.c
++++ b/drivers/gpu/drm/radeon/ni.c
+@@ -2373,7 +2373,7 @@ int cayman_init(struct radeon_device *rdev)
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* Fence driver */
+ radeon_fence_driver_init(rdev);
+ /* initialize memory controller */
+diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
+index b63b6b4e9b2818..54cbfac3605fb3 100644
+--- a/drivers/gpu/drm/radeon/r100.c
++++ b/drivers/gpu/drm/radeon/r100.c
+@@ -458,7 +458,7 @@ void r100_pm_misc(struct radeon_device *rdev)
+ */
+ void r100_pm_prepare(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 tmp;
+@@ -489,7 +489,7 @@ void r100_pm_prepare(struct radeon_device *rdev)
+ */
+ void r100_pm_finish(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 tmp;
+@@ -602,7 +602,7 @@ void r100_hpd_set_polarity(struct radeon_device *rdev,
+ */
+ void r100_hpd_init(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned enable = 0;
+
+@@ -625,7 +625,7 @@ void r100_hpd_init(struct radeon_device *rdev)
+ */
+ void r100_hpd_fini(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned disable = 0;
+
+@@ -797,7 +797,7 @@ int r100_irq_process(struct radeon_device *rdev)
+ /* Vertical blank interrupts */
+ if (status & RADEON_CRTC_VBLANK_STAT) {
+ if (rdev->irq.crtc_vblank_int[0]) {
+- drm_handle_vblank(rdev->ddev, 0);
++ drm_handle_vblank(rdev_to_drm(rdev), 0);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -806,7 +806,7 @@ int r100_irq_process(struct radeon_device *rdev)
+ }
+ if (status & RADEON_CRTC2_VBLANK_STAT) {
+ if (rdev->irq.crtc_vblank_int[1]) {
+- drm_handle_vblank(rdev->ddev, 1);
++ drm_handle_vblank(rdev_to_drm(rdev), 1);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -1490,7 +1490,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
+ header = radeon_get_ib_value(p, h_idx);
+ crtc_id = radeon_get_ib_value(p, h_idx + 5);
+ reg = R100_CP_PACKET0_GET_REG(header);
+- crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
++ crtc = drm_crtc_find(rdev_to_drm(p->rdev), p->filp, crtc_id);
+ if (!crtc) {
+ DRM_ERROR("cannot find crtc %d\n", crtc_id);
+ return -ENOENT;
+@@ -3078,7 +3078,7 @@ DEFINE_SHOW_ATTRIBUTE(r100_debugfs_mc_info);
+ void r100_debugfs_rbbm_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("r100_rbbm_info", 0444, root, rdev,
+ &r100_debugfs_rbbm_info_fops);
+@@ -3088,7 +3088,7 @@ void r100_debugfs_rbbm_init(struct radeon_device *rdev)
+ void r100_debugfs_cp_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("r100_cp_ring_info", 0444, root, rdev,
+ &r100_debugfs_cp_ring_info_fops);
+@@ -3100,7 +3100,7 @@ void r100_debugfs_cp_init(struct radeon_device *rdev)
+ void r100_debugfs_mc_info_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("r100_mc_info", 0444, root, rdev,
+ &r100_debugfs_mc_info_fops);
+@@ -3966,7 +3966,7 @@ int r100_resume(struct radeon_device *rdev)
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+- radeon_combios_asic_init(rdev->ddev);
++ radeon_combios_asic_init(rdev_to_drm(rdev));
+ /* Resume clock after posting */
+ r100_clock_startup(rdev);
+ /* Initialize surface registers */
+@@ -4075,7 +4075,7 @@ int r100_init(struct radeon_device *rdev)
+ /* Set asic errata */
+ r100_errata(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize AGP */
+ if (rdev->flags & RADEON_IS_AGP) {
+ r = radeon_agp_init(rdev);
+diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
+index 25201b9a5aae7d..430a4263ccf7a8 100644
+--- a/drivers/gpu/drm/radeon/r300.c
++++ b/drivers/gpu/drm/radeon/r300.c
+@@ -615,7 +615,7 @@ DEFINE_SHOW_ATTRIBUTE(rv370_debugfs_pcie_gart_info);
+ static void rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("rv370_pcie_gart_info", 0444, root, rdev,
+ &rv370_debugfs_pcie_gart_info_fops);
+@@ -1451,7 +1451,7 @@ int r300_resume(struct radeon_device *rdev)
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+- radeon_combios_asic_init(rdev->ddev);
++ radeon_combios_asic_init(rdev_to_drm(rdev));
+ /* Resume clock after posting */
+ r300_clock_startup(rdev);
+ /* Initialize surface registers */
+@@ -1537,7 +1537,7 @@ int r300_init(struct radeon_device *rdev)
+ /* Set asic errata */
+ r300_errata(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize AGP */
+ if (rdev->flags & RADEON_IS_AGP) {
+ r = radeon_agp_init(rdev);
+diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
+index eae8a6389f5ea2..b3a747a8f17d55 100644
+--- a/drivers/gpu/drm/radeon/r420.c
++++ b/drivers/gpu/drm/radeon/r420.c
+@@ -321,7 +321,7 @@ int r420_resume(struct radeon_device *rdev)
+ if (rdev->is_atom_bios) {
+ atom_asic_init(rdev->mode_info.atom_context);
+ } else {
+- radeon_combios_asic_init(rdev->ddev);
++ radeon_combios_asic_init(rdev_to_drm(rdev));
+ }
+ /* Resume clock after posting */
+ r420_clock_resume(rdev);
+@@ -413,7 +413,7 @@ int r420_init(struct radeon_device *rdev)
+ return -EINVAL;
+
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize AGP */
+ if (rdev->flags & RADEON_IS_AGP) {
+ r = radeon_agp_init(rdev);
+@@ -492,7 +492,7 @@ DEFINE_SHOW_ATTRIBUTE(r420_debugfs_pipes_info);
+ void r420_debugfs_pipes_info_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("r420_pipes_info", 0444, root, rdev,
+ &r420_debugfs_pipes_info_fops);
+diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
+index 6cbcaa8451924c..08e127b3249a22 100644
+--- a/drivers/gpu/drm/radeon/r520.c
++++ b/drivers/gpu/drm/radeon/r520.c
+@@ -287,7 +287,7 @@ int r520_init(struct radeon_device *rdev)
+ atom_asic_init(rdev->mode_info.atom_context);
+ }
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize AGP */
+ if (rdev->flags & RADEON_IS_AGP) {
+ r = radeon_agp_init(rdev);
+diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
+index a17b95eec65fb8..98d075c540e5e5 100644
+--- a/drivers/gpu/drm/radeon/r600.c
++++ b/drivers/gpu/drm/radeon/r600.c
+@@ -950,7 +950,7 @@ void r600_hpd_set_polarity(struct radeon_device *rdev,
+
+ void r600_hpd_init(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned enable = 0;
+
+@@ -1017,7 +1017,7 @@ void r600_hpd_init(struct radeon_device *rdev)
+
+ void r600_hpd_fini(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned disable = 0;
+
+@@ -3280,7 +3280,7 @@ int r600_init(struct radeon_device *rdev)
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* Fence driver */
+ radeon_fence_driver_init(rdev);
+ if (rdev->flags & RADEON_IS_AGP) {
+@@ -4136,7 +4136,7 @@ int r600_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[0]) {
+- drm_handle_vblank(rdev->ddev, 0);
++ drm_handle_vblank(rdev_to_drm(rdev), 0);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -4166,7 +4166,7 @@ int r600_irq_process(struct radeon_device *rdev)
+ DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n");
+
+ if (rdev->irq.crtc_vblank_int[1]) {
+- drm_handle_vblank(rdev->ddev, 1);
++ drm_handle_vblank(rdev_to_drm(rdev), 1);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -4358,7 +4358,7 @@ DEFINE_SHOW_ATTRIBUTE(r600_debugfs_mc_info);
+ static void r600_debugfs_mc_info_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("r600_mc_info", 0444, root, rdev,
+ &r600_debugfs_mc_info_fops);
+diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
+index 6cf54a747749d3..1b2d31c4d77caa 100644
+--- a/drivers/gpu/drm/radeon/r600_cs.c
++++ b/drivers/gpu/drm/radeon/r600_cs.c
+@@ -884,7 +884,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
+ crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
+ reg = R600_CP_PACKET0_GET_REG(header);
+
+- crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
++ crtc = drm_crtc_find(rdev_to_drm(p->rdev), p->filp, crtc_id);
+ if (!crtc) {
+ DRM_ERROR("cannot find crtc %d\n", crtc_id);
+ return -ENOENT;
+diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c
+index 9d2bcb9551e612..157107cf1bfb0d 100644
+--- a/drivers/gpu/drm/radeon/r600_dpm.c
++++ b/drivers/gpu/drm/radeon/r600_dpm.c
+@@ -155,7 +155,7 @@ void r600_dpm_print_ps_status(struct radeon_device *rdev,
+
+ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 vblank_in_pixels;
+@@ -182,7 +182,7 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
+
+ u32 r600_dpm_get_vrefresh(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 vrefresh = 0;
+diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
+index f3551ebaa2f08a..661f374f5f27a7 100644
+--- a/drivers/gpu/drm/radeon/r600_hdmi.c
++++ b/drivers/gpu/drm/radeon/r600_hdmi.c
+@@ -116,7 +116,7 @@ void r600_audio_update_hdmi(struct work_struct *work)
+ {
+ struct radeon_device *rdev = container_of(work, struct radeon_device,
+ audio_work);
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct r600_audio_pin audio_status = r600_audio_status(rdev);
+ struct drm_encoder *encoder;
+ bool changed = false;
+diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
+index 426a49851e3497..e0a02b357ce723 100644
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -2478,6 +2478,11 @@ void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v);
+ u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index);
+ void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v);
+
++static inline struct drm_device *rdev_to_drm(struct radeon_device *rdev)
++{
++ return rdev->ddev;
++}
++
+ /*
+ * Cast helper
+ */
+diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
+index 603a78e41ba55c..22ce61bdfc0603 100644
+--- a/drivers/gpu/drm/radeon/radeon_acpi.c
++++ b/drivers/gpu/drm/radeon/radeon_acpi.c
+@@ -405,11 +405,11 @@ static int radeon_atif_handler(struct radeon_device *rdev,
+ if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
+ if ((rdev->flags & RADEON_IS_PX) &&
+ radeon_atpx_dgpu_req_power_for_displays()) {
+- pm_runtime_get_sync(rdev->ddev->dev);
++ pm_runtime_get_sync(rdev_to_drm(rdev)->dev);
+ /* Just fire off a uevent and let userspace tell us what to do */
+- drm_helper_hpd_irq_event(rdev->ddev);
+- pm_runtime_mark_last_busy(rdev->ddev->dev);
+- pm_runtime_put_autosuspend(rdev->ddev->dev);
++ drm_helper_hpd_irq_event(rdev_to_drm(rdev));
++ pm_runtime_mark_last_busy(rdev_to_drm(rdev)->dev);
++ pm_runtime_put_autosuspend(rdev_to_drm(rdev)->dev);
+ }
+ }
+ /* TODO: check other events */
+@@ -736,7 +736,7 @@ int radeon_acpi_init(struct radeon_device *rdev)
+ struct radeon_encoder *target = NULL;
+
+ /* Find the encoder controlling the brightness */
+- list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
++ list_for_each_entry(tmp, &rdev_to_drm(rdev)->mode_config.encoder_list,
+ head) {
+ struct radeon_encoder *enc = to_radeon_encoder(tmp);
+
+diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c
+index a3d749e350f9c2..89d7b0e9e79f82 100644
+--- a/drivers/gpu/drm/radeon/radeon_agp.c
++++ b/drivers/gpu/drm/radeon/radeon_agp.c
+@@ -161,7 +161,7 @@ struct radeon_agp_head *radeon_agp_head_init(struct drm_device *dev)
+
+ static int radeon_agp_head_acquire(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct pci_dev *pdev = to_pci_dev(dev->dev);
+
+ if (!rdev->agp)
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index 53c7273eb6a5cf..c025ce6eb31672 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -186,7 +186,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
+
+ if (i2c.valid) {
+ sprintf(stmp, "0x%x", i2c.i2c_id);
+- rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp);
++ rdev->i2c_bus[i] = radeon_i2c_create(rdev_to_drm(rdev), &i2c, stmp);
+ }
+ gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
+ ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
+diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
+index d6ccaf24ee0c70..fc22fe709b9c1b 100644
+--- a/drivers/gpu/drm/radeon/radeon_audio.c
++++ b/drivers/gpu/drm/radeon/radeon_audio.c
+@@ -195,7 +195,7 @@ static void radeon_audio_enable(struct radeon_device *rdev,
+ return;
+
+ if (rdev->mode_info.mode_config_initialized) {
+- list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
++ list_for_each_entry(encoder, &rdev_to_drm(rdev)->mode_config.encoder_list, head) {
+ if (radeon_encoder_is_digital(encoder)) {
+ radeon_encoder = to_radeon_encoder(encoder);
+ dig = radeon_encoder->enc_priv;
+@@ -758,16 +758,20 @@ static int radeon_audio_component_get_eld(struct device *kdev, int port,
+ if (!rdev->audio.enabled || !rdev->mode_info.mode_config_initialized)
+ return 0;
+
+- list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
++ const struct drm_connector_helper_funcs *connector_funcs =
++ connector->helper_private;
++ encoder = connector_funcs->best_encoder(connector);
++
++ if (!encoder)
++ continue;
++
+ if (!radeon_encoder_is_digital(encoder))
+ continue;
+ radeon_encoder = to_radeon_encoder(encoder);
+ dig = radeon_encoder->enc_priv;
+ if (!dig->pin || dig->pin->id != port)
+ continue;
+- connector = radeon_get_connector_for_encoder(encoder);
+- if (!connector)
+- continue;
+ *enabled = true;
+ ret = drm_eld_size(connector->eld);
+ memcpy(buf, connector->eld, min(max_bytes, ret));
+diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
+index 2620efc7c675bf..a30f36d098a8d1 100644
+--- a/drivers/gpu/drm/radeon/radeon_combios.c
++++ b/drivers/gpu/drm/radeon/radeon_combios.c
+@@ -371,7 +371,7 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
+ int edid_info, size;
+ struct edid *edid;
+ unsigned char *raw;
+- edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
++ edid_info = combios_get_table_offset(rdev_to_drm(rdev), COMBIOS_HARDCODED_EDID_TABLE);
+ if (!edid_info)
+ return false;
+
+@@ -641,7 +641,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
+
+ static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct radeon_i2c_bus_rec i2c;
+ u16 offset;
+ u8 id, blocks, clk, data;
+@@ -669,7 +669,7 @@ static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct r
+
+ void radeon_combios_i2c_init(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct radeon_i2c_bus_rec i2c;
+
+ /* actual hw pads
+@@ -811,7 +811,7 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
+
+ bool radeon_combios_sideport_present(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ u16 igp_info;
+
+ /* sideport is AMD only */
+@@ -914,7 +914,7 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
+ enum radeon_tv_std
+ radeon_combios_get_tv_info(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ uint16_t tv_info;
+ enum radeon_tv_std tv_std = TV_STD_NTSC;
+
+@@ -2636,7 +2636,7 @@ static const char *thermal_controller_names[] = {
+
+ void radeon_combios_get_power_modes(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ u16 offset, misc, misc2 = 0;
+ u8 rev, tmp;
+ int state_index = 0;
+diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
+index afbb3a80c0c6b5..32851632643db9 100644
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -760,7 +760,7 @@ bool radeon_boot_test_post_card(struct radeon_device *rdev)
+ if (rdev->is_atom_bios)
+ atom_asic_init(rdev->mode_info.atom_context);
+ else
+- radeon_combios_asic_init(rdev->ddev);
++ radeon_combios_asic_init(rdev_to_drm(rdev));
+ return true;
+ } else {
+ dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
+@@ -980,7 +980,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
+ return -ENOMEM;
+
+ rdev->mode_info.atom_card_info = atom_card_info;
+- atom_card_info->dev = rdev->ddev;
++ atom_card_info->dev = rdev_to_drm(rdev);
+ atom_card_info->reg_read = cail_reg_read;
+ atom_card_info->reg_write = cail_reg_write;
+ /* needed for iio ops */
+@@ -1005,7 +1005,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
+
+ mutex_init(&rdev->mode_info.atom_context->mutex);
+ mutex_init(&rdev->mode_info.atom_context->scratch_mutex);
+- radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
++ radeon_atom_initialize_bios_scratch_regs(rdev_to_drm(rdev));
+ atom_allocate_fb_scratch(rdev->mode_info.atom_context);
+ return 0;
+ }
+@@ -1049,7 +1049,7 @@ void radeon_atombios_fini(struct radeon_device *rdev)
+ */
+ int radeon_combios_init(struct radeon_device *rdev)
+ {
+- radeon_combios_initialize_bios_scratch_regs(rdev->ddev);
++ radeon_combios_initialize_bios_scratch_regs(rdev_to_drm(rdev));
+ return 0;
+ }
+
+@@ -1847,7 +1847,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
+
+ downgrade_write(&rdev->exclusive_lock);
+
+- drm_helper_resume_force_mode(rdev->ddev);
++ drm_helper_resume_force_mode(rdev_to_drm(rdev));
+
+ /* set the power state here in case we are a PX system or headless */
+ if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled)
+diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
+index 5f1d24d3120c4a..8a8ffc5fc8040b 100644
+--- a/drivers/gpu/drm/radeon/radeon_display.c
++++ b/drivers/gpu/drm/radeon/radeon_display.c
+@@ -302,13 +302,13 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
+ if ((radeon_use_pflipirq == 2) && ASIC_IS_DCE4(rdev))
+ return;
+
+- spin_lock_irqsave(&rdev->ddev->event_lock, flags);
++ spin_lock_irqsave(&rdev_to_drm(rdev)->event_lock, flags);
+ if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
+ DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
+ "RADEON_FLIP_SUBMITTED(%d)\n",
+ radeon_crtc->flip_status,
+ RADEON_FLIP_SUBMITTED);
+- spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
++ spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
+ return;
+ }
+
+@@ -334,7 +334,7 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
+ */
+ if (update_pending &&
+ (DRM_SCANOUTPOS_VALID &
+- radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id,
++ radeon_get_crtc_scanoutpos(rdev_to_drm(rdev), crtc_id,
+ GET_DISTANCE_TO_VBLANKSTART,
+ &vpos, &hpos, NULL, NULL,
+ &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) &&
+@@ -347,7 +347,7 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
+ */
+ update_pending = 0;
+ }
+- spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
++ spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
+ if (!update_pending)
+ radeon_crtc_handle_flip(rdev, crtc_id);
+ }
+@@ -370,14 +370,14 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
+ if (radeon_crtc == NULL)
+ return;
+
+- spin_lock_irqsave(&rdev->ddev->event_lock, flags);
++ spin_lock_irqsave(&rdev_to_drm(rdev)->event_lock, flags);
+ work = radeon_crtc->flip_work;
+ if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
+ DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
+ "RADEON_FLIP_SUBMITTED(%d)\n",
+ radeon_crtc->flip_status,
+ RADEON_FLIP_SUBMITTED);
+- spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
++ spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
+ return;
+ }
+
+@@ -389,7 +389,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
+ if (work->event)
+ drm_crtc_send_vblank_event(&radeon_crtc->base, work->event);
+
+- spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
++ spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
+
+ drm_crtc_vblank_put(&radeon_crtc->base);
+ radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
+@@ -408,7 +408,7 @@ static void radeon_flip_work_func(struct work_struct *__work)
+ struct radeon_flip_work *work =
+ container_of(__work, struct radeon_flip_work, flip_work);
+ struct radeon_device *rdev = work->rdev;
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
+
+ struct drm_crtc *crtc = &radeon_crtc->base;
+@@ -1401,7 +1401,7 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
+
+ if (rdev->is_atom_bios) {
+ rdev->mode_info.coherent_mode_property =
+- drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1);
++ drm_property_create_range(rdev_to_drm(rdev), 0, "coherent", 0, 1);
+ if (!rdev->mode_info.coherent_mode_property)
+ return -ENOMEM;
+ }
+@@ -1409,57 +1409,57 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
+ if (!ASIC_IS_AVIVO(rdev)) {
+ sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
+ rdev->mode_info.tmds_pll_property =
+- drm_property_create_enum(rdev->ddev, 0,
++ drm_property_create_enum(rdev_to_drm(rdev), 0,
+ "tmds_pll",
+ radeon_tmds_pll_enum_list, sz);
+ }
+
+ rdev->mode_info.load_detect_property =
+- drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1);
++ drm_property_create_range(rdev_to_drm(rdev), 0, "load detection", 0, 1);
+ if (!rdev->mode_info.load_detect_property)
+ return -ENOMEM;
+
+- drm_mode_create_scaling_mode_property(rdev->ddev);
++ drm_mode_create_scaling_mode_property(rdev_to_drm(rdev));
+
+ sz = ARRAY_SIZE(radeon_tv_std_enum_list);
+ rdev->mode_info.tv_std_property =
+- drm_property_create_enum(rdev->ddev, 0,
++ drm_property_create_enum(rdev_to_drm(rdev), 0,
+ "tv standard",
+ radeon_tv_std_enum_list, sz);
+
+ sz = ARRAY_SIZE(radeon_underscan_enum_list);
+ rdev->mode_info.underscan_property =
+- drm_property_create_enum(rdev->ddev, 0,
++ drm_property_create_enum(rdev_to_drm(rdev), 0,
+ "underscan",
+ radeon_underscan_enum_list, sz);
+
+ rdev->mode_info.underscan_hborder_property =
+- drm_property_create_range(rdev->ddev, 0,
++ drm_property_create_range(rdev_to_drm(rdev), 0,
+ "underscan hborder", 0, 128);
+ if (!rdev->mode_info.underscan_hborder_property)
+ return -ENOMEM;
+
+ rdev->mode_info.underscan_vborder_property =
+- drm_property_create_range(rdev->ddev, 0,
++ drm_property_create_range(rdev_to_drm(rdev), 0,
+ "underscan vborder", 0, 128);
+ if (!rdev->mode_info.underscan_vborder_property)
+ return -ENOMEM;
+
+ sz = ARRAY_SIZE(radeon_audio_enum_list);
+ rdev->mode_info.audio_property =
+- drm_property_create_enum(rdev->ddev, 0,
++ drm_property_create_enum(rdev_to_drm(rdev), 0,
+ "audio",
+ radeon_audio_enum_list, sz);
+
+ sz = ARRAY_SIZE(radeon_dither_enum_list);
+ rdev->mode_info.dither_property =
+- drm_property_create_enum(rdev->ddev, 0,
++ drm_property_create_enum(rdev_to_drm(rdev), 0,
+ "dither",
+ radeon_dither_enum_list, sz);
+
+ sz = ARRAY_SIZE(radeon_output_csc_enum_list);
+ rdev->mode_info.output_csc_property =
+- drm_property_create_enum(rdev->ddev, 0,
++ drm_property_create_enum(rdev_to_drm(rdev), 0,
+ "output_csc",
+ radeon_output_csc_enum_list, sz);
+
+@@ -1578,29 +1578,29 @@ int radeon_modeset_init(struct radeon_device *rdev)
+ int i;
+ int ret;
+
+- drm_mode_config_init(rdev->ddev);
++ drm_mode_config_init(rdev_to_drm(rdev));
+ rdev->mode_info.mode_config_initialized = true;
+
+- rdev->ddev->mode_config.funcs = &radeon_mode_funcs;
++ rdev_to_drm(rdev)->mode_config.funcs = &radeon_mode_funcs;
+
+ if (radeon_use_pflipirq == 2 && rdev->family >= CHIP_R600)
+- rdev->ddev->mode_config.async_page_flip = true;
++ rdev_to_drm(rdev)->mode_config.async_page_flip = true;
+
+ if (ASIC_IS_DCE5(rdev)) {
+- rdev->ddev->mode_config.max_width = 16384;
+- rdev->ddev->mode_config.max_height = 16384;
++ rdev_to_drm(rdev)->mode_config.max_width = 16384;
++ rdev_to_drm(rdev)->mode_config.max_height = 16384;
+ } else if (ASIC_IS_AVIVO(rdev)) {
+- rdev->ddev->mode_config.max_width = 8192;
+- rdev->ddev->mode_config.max_height = 8192;
++ rdev_to_drm(rdev)->mode_config.max_width = 8192;
++ rdev_to_drm(rdev)->mode_config.max_height = 8192;
+ } else {
+- rdev->ddev->mode_config.max_width = 4096;
+- rdev->ddev->mode_config.max_height = 4096;
++ rdev_to_drm(rdev)->mode_config.max_width = 4096;
++ rdev_to_drm(rdev)->mode_config.max_height = 4096;
+ }
+
+- rdev->ddev->mode_config.preferred_depth = 24;
+- rdev->ddev->mode_config.prefer_shadow = 1;
++ rdev_to_drm(rdev)->mode_config.preferred_depth = 24;
++ rdev_to_drm(rdev)->mode_config.prefer_shadow = 1;
+
+- rdev->ddev->mode_config.fb_modifiers_not_supported = true;
++ rdev_to_drm(rdev)->mode_config.fb_modifiers_not_supported = true;
+
+ ret = radeon_modeset_create_props(rdev);
+ if (ret) {
+@@ -1618,11 +1618,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
+
+ /* allocate crtcs */
+ for (i = 0; i < rdev->num_crtc; i++) {
+- radeon_crtc_init(rdev->ddev, i);
++ radeon_crtc_init(rdev_to_drm(rdev), i);
+ }
+
+ /* okay we should have all the bios connectors */
+- ret = radeon_setup_enc_conn(rdev->ddev);
++ ret = radeon_setup_enc_conn(rdev_to_drm(rdev));
+ if (!ret) {
+ return ret;
+ }
+@@ -1639,7 +1639,7 @@ int radeon_modeset_init(struct radeon_device *rdev)
+ /* setup afmt */
+ radeon_afmt_init(rdev);
+
+- drm_kms_helper_poll_init(rdev->ddev);
++ drm_kms_helper_poll_init(rdev_to_drm(rdev));
+
+ /* do pm late init */
+ ret = radeon_pm_late_init(rdev);
+@@ -1650,11 +1650,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
+ void radeon_modeset_fini(struct radeon_device *rdev)
+ {
+ if (rdev->mode_info.mode_config_initialized) {
+- drm_kms_helper_poll_fini(rdev->ddev);
++ drm_kms_helper_poll_fini(rdev_to_drm(rdev));
+ radeon_hpd_fini(rdev);
+- drm_helper_force_disable_all(rdev->ddev);
++ drm_helper_force_disable_all(rdev_to_drm(rdev));
+ radeon_afmt_fini(rdev);
+- drm_mode_config_cleanup(rdev->ddev);
++ drm_mode_config_cleanup(rdev_to_drm(rdev));
+ rdev->mode_info.mode_config_initialized = false;
+ }
+
+diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c b/drivers/gpu/drm/radeon/radeon_fbdev.c
+index 02bf25759059a7..fb70de29545c6f 100644
+--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
++++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
+@@ -67,7 +67,7 @@ static int radeon_fbdev_create_pinned_object(struct drm_fb_helper *fb_helper,
+ int height = mode_cmd->height;
+ u32 cpp;
+
+- info = drm_get_format_info(rdev->ddev, mode_cmd);
++ info = drm_get_format_info(rdev_to_drm(rdev), mode_cmd);
+ cpp = info->cpp[0];
+
+ /* need to align pitch with crtc limits */
+@@ -148,15 +148,15 @@ static int radeon_fbdev_fb_open(struct fb_info *info, int user)
+ struct radeon_device *rdev = fb_helper->dev->dev_private;
+ int ret;
+
+- ret = pm_runtime_get_sync(rdev->ddev->dev);
++ ret = pm_runtime_get_sync(rdev_to_drm(rdev)->dev);
+ if (ret < 0 && ret != -EACCES)
+ goto err_pm_runtime_mark_last_busy;
+
+ return 0;
+
+ err_pm_runtime_mark_last_busy:
+- pm_runtime_mark_last_busy(rdev->ddev->dev);
+- pm_runtime_put_autosuspend(rdev->ddev->dev);
++ pm_runtime_mark_last_busy(rdev_to_drm(rdev)->dev);
++ pm_runtime_put_autosuspend(rdev_to_drm(rdev)->dev);
+ return ret;
+ }
+
+@@ -165,8 +165,8 @@ static int radeon_fbdev_fb_release(struct fb_info *info, int user)
+ struct drm_fb_helper *fb_helper = info->par;
+ struct radeon_device *rdev = fb_helper->dev->dev_private;
+
+- pm_runtime_mark_last_busy(rdev->ddev->dev);
+- pm_runtime_put_autosuspend(rdev->ddev->dev);
++ pm_runtime_mark_last_busy(rdev_to_drm(rdev)->dev);
++ pm_runtime_put_autosuspend(rdev_to_drm(rdev)->dev);
+
+ return 0;
+ }
+@@ -236,7 +236,7 @@ static int radeon_fbdev_fb_helper_fb_probe(struct drm_fb_helper *fb_helper,
+ ret = -ENOMEM;
+ goto err_radeon_fbdev_destroy_pinned_object;
+ }
+- ret = radeon_framebuffer_init(rdev->ddev, fb, &mode_cmd, gobj);
++ ret = radeon_framebuffer_init(rdev_to_drm(rdev), fb, &mode_cmd, gobj);
+ if (ret) {
+ DRM_ERROR("failed to initialize framebuffer %d\n", ret);
+ goto err_kfree;
+@@ -374,12 +374,12 @@ void radeon_fbdev_setup(struct radeon_device *rdev)
+ fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
+ if (!fb_helper)
+ return;
+- drm_fb_helper_prepare(rdev->ddev, fb_helper, bpp_sel, &radeon_fbdev_fb_helper_funcs);
++ drm_fb_helper_prepare(rdev_to_drm(rdev), fb_helper, bpp_sel, &radeon_fbdev_fb_helper_funcs);
+
+- ret = drm_client_init(rdev->ddev, &fb_helper->client, "radeon-fbdev",
++ ret = drm_client_init(rdev_to_drm(rdev), &fb_helper->client, "radeon-fbdev",
+ &radeon_fbdev_client_funcs);
+ if (ret) {
+- drm_err(rdev->ddev, "Failed to register client: %d\n", ret);
++ drm_err(rdev_to_drm(rdev), "Failed to register client: %d\n", ret);
+ goto err_drm_client_init;
+ }
+
+@@ -394,13 +394,13 @@ void radeon_fbdev_setup(struct radeon_device *rdev)
+
+ void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
+ {
+- if (rdev->ddev->fb_helper)
+- drm_fb_helper_set_suspend(rdev->ddev->fb_helper, state);
++ if (rdev_to_drm(rdev)->fb_helper)
++ drm_fb_helper_set_suspend(rdev_to_drm(rdev)->fb_helper, state);
+ }
+
+ bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
+ {
+- struct drm_fb_helper *fb_helper = rdev->ddev->fb_helper;
++ struct drm_fb_helper *fb_helper = rdev_to_drm(rdev)->fb_helper;
+ struct drm_gem_object *gobj;
+
+ if (!fb_helper)
+diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
+index 2749dde5838f1c..6d5e828fa39e3d 100644
+--- a/drivers/gpu/drm/radeon/radeon_fence.c
++++ b/drivers/gpu/drm/radeon/radeon_fence.c
+@@ -151,7 +151,7 @@ int radeon_fence_emit(struct radeon_device *rdev,
+ rdev->fence_context + ring,
+ seq);
+ radeon_fence_ring_emit(rdev, ring, *fence);
+- trace_radeon_fence_emit(rdev->ddev, ring, (*fence)->seq);
++ trace_radeon_fence_emit(rdev_to_drm(rdev), ring, (*fence)->seq);
+ radeon_fence_schedule_check(rdev, ring);
+ return 0;
+ }
+@@ -492,7 +492,7 @@ static long radeon_fence_wait_seq_timeout(struct radeon_device *rdev,
+ if (!target_seq[i])
+ continue;
+
+- trace_radeon_fence_wait_begin(rdev->ddev, i, target_seq[i]);
++ trace_radeon_fence_wait_begin(rdev_to_drm(rdev), i, target_seq[i]);
+ radeon_irq_kms_sw_irq_get(rdev, i);
+ }
+
+@@ -514,7 +514,7 @@ static long radeon_fence_wait_seq_timeout(struct radeon_device *rdev,
+ continue;
+
+ radeon_irq_kms_sw_irq_put(rdev, i);
+- trace_radeon_fence_wait_end(rdev->ddev, i, target_seq[i]);
++ trace_radeon_fence_wait_end(rdev_to_drm(rdev), i, target_seq[i]);
+ }
+
+ return r;
+@@ -1004,7 +1004,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(radeon_debugfs_gpu_reset_fops,
+ void radeon_debugfs_fence_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("radeon_gpu_reset", 0444, root, rdev,
+ &radeon_debugfs_gpu_reset_fops);
+diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
+index 27225d1fe8d2e7..96934fee7e9432 100644
+--- a/drivers/gpu/drm/radeon/radeon_gem.c
++++ b/drivers/gpu/drm/radeon/radeon_gem.c
+@@ -898,7 +898,7 @@ DEFINE_SHOW_ATTRIBUTE(radeon_debugfs_gem_info);
+ void radeon_gem_debugfs_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("radeon_gem_info", 0444, root, rdev,
+ &radeon_debugfs_gem_info_fops);
+diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
+index 314d066e68e9d0..e7b2e937072942 100644
+--- a/drivers/gpu/drm/radeon/radeon_i2c.c
++++ b/drivers/gpu/drm/radeon/radeon_i2c.c
+@@ -1012,7 +1012,7 @@ void radeon_i2c_add(struct radeon_device *rdev,
+ struct radeon_i2c_bus_rec *rec,
+ const char *name)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ int i;
+
+ for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
+diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c
+index fb9ecf5dbe2b7a..560ce90f4eb16a 100644
+--- a/drivers/gpu/drm/radeon/radeon_ib.c
++++ b/drivers/gpu/drm/radeon/radeon_ib.c
+@@ -307,7 +307,7 @@ DEFINE_SHOW_ATTRIBUTE(radeon_debugfs_sa_info);
+ static void radeon_debugfs_sa_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("radeon_sa_info", 0444, root, rdev,
+ &radeon_debugfs_sa_info_fops);
+diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+index c4dda908666cfc..9961251b44ba06 100644
+--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+@@ -80,7 +80,7 @@ static void radeon_hotplug_work_func(struct work_struct *work)
+ {
+ struct radeon_device *rdev = container_of(work, struct radeon_device,
+ hotplug_work.work);
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_mode_config *mode_config = &dev->mode_config;
+ struct drm_connector *connector;
+
+@@ -101,7 +101,7 @@ static void radeon_dp_work_func(struct work_struct *work)
+ {
+ struct radeon_device *rdev = container_of(work, struct radeon_device,
+ dp_work);
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_mode_config *mode_config = &dev->mode_config;
+ struct drm_connector *connector;
+
+@@ -197,7 +197,7 @@ static void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
+
+ static int radeon_irq_install(struct radeon_device *rdev, int irq)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ int ret;
+
+ if (irq == IRQ_NOTCONNECTED)
+@@ -218,7 +218,7 @@ static int radeon_irq_install(struct radeon_device *rdev, int irq)
+
+ static void radeon_irq_uninstall(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct pci_dev *pdev = to_pci_dev(dev->dev);
+
+ radeon_driver_irq_uninstall_kms(dev);
+@@ -322,9 +322,9 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
+ spin_lock_init(&rdev->irq.lock);
+
+ /* Disable vblank irqs aggressively for power-saving */
+- rdev->ddev->vblank_disable_immediate = true;
++ rdev_to_drm(rdev)->vblank_disable_immediate = true;
+
+- r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
++ r = drm_vblank_init(rdev_to_drm(rdev), rdev->num_crtc);
+ if (r) {
+ return r;
+ }
+diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
+index 10c0fbd9d2b441..6f3c9a20a2de58 100644
+--- a/drivers/gpu/drm/radeon/radeon_object.c
++++ b/drivers/gpu/drm/radeon/radeon_object.c
+@@ -152,7 +152,7 @@ int radeon_bo_create(struct radeon_device *rdev,
+ bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
+ if (bo == NULL)
+ return -ENOMEM;
+- drm_gem_private_object_init(rdev->ddev, &bo->tbo.base, size);
++ drm_gem_private_object_init(rdev_to_drm(rdev), &bo->tbo.base, size);
+ bo->rdev = rdev;
+ bo->surface_reg = -1;
+ INIT_LIST_HEAD(&bo->list);
+diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
+index b73fd9ab02522a..66fe9fb920452a 100644
+--- a/drivers/gpu/drm/radeon/radeon_pm.c
++++ b/drivers/gpu/drm/radeon/radeon_pm.c
+@@ -281,7 +281,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
+
+ if (rdev->irq.installed) {
+ i = 0;
+- drm_for_each_crtc(crtc, rdev->ddev) {
++ drm_for_each_crtc(crtc, rdev_to_drm(rdev)) {
+ if (rdev->pm.active_crtcs & (1 << i)) {
+ /* This can fail if a modeset is in progress */
+ if (drm_crtc_vblank_get(crtc) == 0)
+@@ -298,7 +298,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
+
+ if (rdev->irq.installed) {
+ i = 0;
+- drm_for_each_crtc(crtc, rdev->ddev) {
++ drm_for_each_crtc(crtc, rdev_to_drm(rdev)) {
+ if (rdev->pm.req_vblank & (1 << i)) {
+ rdev->pm.req_vblank &= ~(1 << i);
+ drm_crtc_vblank_put(crtc);
+@@ -670,7 +670,7 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
+ char *buf)
+ {
+ struct radeon_device *rdev = dev_get_drvdata(dev);
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ int temp;
+
+ /* Can't get temperature when the card is off */
+@@ -714,7 +714,7 @@ static ssize_t radeon_hwmon_show_sclk(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct radeon_device *rdev = dev_get_drvdata(dev);
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ u32 sclk = 0;
+
+ /* Can't get clock frequency when the card is off */
+@@ -739,7 +739,7 @@ static ssize_t radeon_hwmon_show_vddc(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct radeon_device *rdev = dev_get_drvdata(dev);
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ u16 vddc = 0;
+
+ /* Can't get vddc when the card is off */
+@@ -1691,7 +1691,7 @@ void radeon_pm_fini(struct radeon_device *rdev)
+
+ static void radeon_pm_compute_clocks_old(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+
+@@ -1764,7 +1764,7 @@ static void radeon_pm_compute_clocks_old(struct radeon_device *rdev)
+
+ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ struct radeon_connector *radeon_connector;
+@@ -1825,7 +1825,7 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev)
+ */
+ for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) {
+ if (rdev->pm.active_crtcs & (1 << crtc)) {
+- vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev,
++ vbl_status = radeon_get_crtc_scanoutpos(rdev_to_drm(rdev),
+ crtc,
+ USE_REAL_VBLANKSTART,
+ &vpos, &hpos, NULL, NULL,
+@@ -1917,7 +1917,7 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work)
+ static int radeon_debugfs_pm_info_show(struct seq_file *m, void *unused)
+ {
+ struct radeon_device *rdev = m->private;
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+
+ if ((rdev->flags & RADEON_IS_PX) &&
+ (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
+@@ -1954,7 +1954,7 @@ DEFINE_SHOW_ATTRIBUTE(radeon_debugfs_pm_info);
+ static void radeon_debugfs_pm_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("radeon_pm_info", 0444, root, rdev,
+ &radeon_debugfs_pm_info_fops);
+diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
+index e6534fa9f1fb54..8626171e9a6db2 100644
+--- a/drivers/gpu/drm/radeon/radeon_ring.c
++++ b/drivers/gpu/drm/radeon/radeon_ring.c
+@@ -548,7 +548,7 @@ static void radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_r
+ {
+ #if defined(CONFIG_DEBUG_FS)
+ const char *ring_name = radeon_debugfs_ring_idx_to_name(ring->idx);
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ if (ring_name)
+ debugfs_create_file(ring_name, 0444, root, ring,
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
+index 4eb83ccc4906ad..065a09e7997cdb 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -689,8 +689,8 @@ int radeon_ttm_init(struct radeon_device *rdev)
+
+ /* No others user of address space so set it to 0 */
+ r = ttm_device_init(&rdev->mman.bdev, &radeon_bo_driver, rdev->dev,
+- rdev->ddev->anon_inode->i_mapping,
+- rdev->ddev->vma_offset_manager,
++ rdev_to_drm(rdev)->anon_inode->i_mapping,
++ rdev_to_drm(rdev)->vma_offset_manager,
+ rdev->need_swiotlb,
+ dma_addressing_limited(&rdev->pdev->dev));
+ if (r) {
+@@ -897,7 +897,7 @@ static const struct file_operations radeon_ttm_gtt_fops = {
+ static void radeon_ttm_debugfs_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct drm_minor *minor = rdev->ddev->primary;
++ struct drm_minor *minor = rdev_to_drm(rdev)->primary;
+ struct dentry *root = minor->debugfs_root;
+
+ debugfs_create_file("radeon_vram", 0444, root, rdev,
+diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
+index 922a29e5888027..4f93fe468ec7f9 100644
+--- a/drivers/gpu/drm/radeon/rs400.c
++++ b/drivers/gpu/drm/radeon/rs400.c
+@@ -378,7 +378,7 @@ DEFINE_SHOW_ATTRIBUTE(rs400_debugfs_gart_info);
+ static void rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("rs400_gart_info", 0444, root, rdev,
+ &rs400_debugfs_gart_info_fops);
+@@ -473,7 +473,7 @@ int rs400_resume(struct radeon_device *rdev)
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+- radeon_combios_asic_init(rdev->ddev);
++ radeon_combios_asic_init(rdev_to_drm(rdev));
+ /* Resume clock after posting */
+ r300_clock_startup(rdev);
+ /* Initialize surface registers */
+@@ -551,7 +551,7 @@ int rs400_init(struct radeon_device *rdev)
+ return -EINVAL;
+
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize memory controller */
+ rs400_mc_init(rdev);
+ /* Fence driver */
+diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
+index 8cf87a0a2b2a00..fa4cc2a185dd02 100644
+--- a/drivers/gpu/drm/radeon/rs600.c
++++ b/drivers/gpu/drm/radeon/rs600.c
+@@ -322,7 +322,7 @@ void rs600_pm_misc(struct radeon_device *rdev)
+
+ void rs600_pm_prepare(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 tmp;
+@@ -340,7 +340,7 @@ void rs600_pm_prepare(struct radeon_device *rdev)
+
+ void rs600_pm_finish(struct radeon_device *rdev)
+ {
+- struct drm_device *ddev = rdev->ddev;
++ struct drm_device *ddev = rdev_to_drm(rdev);
+ struct drm_crtc *crtc;
+ struct radeon_crtc *radeon_crtc;
+ u32 tmp;
+@@ -409,7 +409,7 @@ void rs600_hpd_set_polarity(struct radeon_device *rdev,
+
+ void rs600_hpd_init(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned enable = 0;
+
+@@ -436,7 +436,7 @@ void rs600_hpd_init(struct radeon_device *rdev)
+
+ void rs600_hpd_fini(struct radeon_device *rdev)
+ {
+- struct drm_device *dev = rdev->ddev;
++ struct drm_device *dev = rdev_to_drm(rdev);
+ struct drm_connector *connector;
+ unsigned disable = 0;
+
+@@ -798,7 +798,7 @@ int rs600_irq_process(struct radeon_device *rdev)
+ /* Vertical blank interrupts */
+ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
+ if (rdev->irq.crtc_vblank_int[0]) {
+- drm_handle_vblank(rdev->ddev, 0);
++ drm_handle_vblank(rdev_to_drm(rdev), 0);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -807,7 +807,7 @@ int rs600_irq_process(struct radeon_device *rdev)
+ }
+ if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
+ if (rdev->irq.crtc_vblank_int[1]) {
+- drm_handle_vblank(rdev->ddev, 1);
++ drm_handle_vblank(rdev_to_drm(rdev), 1);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -1134,7 +1134,7 @@ int rs600_init(struct radeon_device *rdev)
+ return -EINVAL;
+
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize memory controller */
+ rs600_mc_init(rdev);
+ r100_debugfs_rbbm_init(rdev);
+diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
+index 14fb0819b8c19c..016eb4992803dc 100644
+--- a/drivers/gpu/drm/radeon/rs690.c
++++ b/drivers/gpu/drm/radeon/rs690.c
+@@ -845,7 +845,7 @@ int rs690_init(struct radeon_device *rdev)
+ return -EINVAL;
+
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize memory controller */
+ rs690_mc_init(rdev);
+ rv515_debugfs(rdev);
+diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
+index 76260fdfbaa725..19a26d85e029c2 100644
+--- a/drivers/gpu/drm/radeon/rv515.c
++++ b/drivers/gpu/drm/radeon/rv515.c
+@@ -255,7 +255,7 @@ DEFINE_SHOW_ATTRIBUTE(rv515_debugfs_ga_info);
+ void rv515_debugfs(struct radeon_device *rdev)
+ {
+ #if defined(CONFIG_DEBUG_FS)
+- struct dentry *root = rdev->ddev->primary->debugfs_root;
++ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
+
+ debugfs_create_file("rv515_pipes_info", 0444, root, rdev,
+ &rv515_debugfs_pipes_info_fops);
+@@ -636,7 +636,7 @@ int rv515_init(struct radeon_device *rdev)
+ if (radeon_boot_test_post_card(rdev) == false)
+ return -EINVAL;
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* initialize AGP */
+ if (rdev->flags & RADEON_IS_AGP) {
+ r = radeon_agp_init(rdev);
+diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
+index 9ce12fa3c35683..7d4b0bf591090a 100644
+--- a/drivers/gpu/drm/radeon/rv770.c
++++ b/drivers/gpu/drm/radeon/rv770.c
+@@ -1935,7 +1935,7 @@ int rv770_init(struct radeon_device *rdev)
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+ /* Fence driver */
+ radeon_fence_driver_init(rdev);
+ /* initialize AGP */
+diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
+index 85e9cba49cecb2..312fe76944a943 100644
+--- a/drivers/gpu/drm/radeon/si.c
++++ b/drivers/gpu/drm/radeon/si.c
+@@ -6296,7 +6296,7 @@ int si_irq_process(struct radeon_device *rdev)
+ event_name = "vblank";
+
+ if (rdev->irq.crtc_vblank_int[crtc_idx]) {
+- drm_handle_vblank(rdev->ddev, crtc_idx);
++ drm_handle_vblank(rdev_to_drm(rdev), crtc_idx);
+ rdev->pm.vblank_sync = true;
+ wake_up(&rdev->irq.vblank_queue);
+ }
+@@ -6858,7 +6858,7 @@ int si_init(struct radeon_device *rdev)
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* Initialize clocks */
+- radeon_get_clock_info(rdev->ddev);
++ radeon_get_clock_info(rdev_to_drm(rdev));
+
+ /* Fence driver */
+ radeon_fence_driver_init(rdev);
+diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c
+index db0a1eb535328f..c59fcb4dca3249 100644
+--- a/drivers/gpu/drm/sti/sti_cursor.c
++++ b/drivers/gpu/drm/sti/sti_cursor.c
+@@ -200,6 +200,9 @@ static int sti_cursor_atomic_check(struct drm_plane *drm_plane,
+ return 0;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
++ if (IS_ERR(crtc_state))
++ return PTR_ERR(crtc_state);
++
+ mode = &crtc_state->mode;
+ dst_x = new_plane_state->crtc_x;
+ dst_y = new_plane_state->crtc_y;
+diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
+index 43c72c2604a0cd..f046f5f7ad259d 100644
+--- a/drivers/gpu/drm/sti/sti_gdp.c
++++ b/drivers/gpu/drm/sti/sti_gdp.c
+@@ -638,6 +638,9 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane,
+
+ mixer = to_sti_mixer(crtc);
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
++ if (IS_ERR(crtc_state))
++ return PTR_ERR(crtc_state);
++
+ mode = &crtc_state->mode;
+ dst_x = new_plane_state->crtc_x;
+ dst_y = new_plane_state->crtc_y;
+diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
+index 0fb48ac044d8a0..abab92df78bd24 100644
+--- a/drivers/gpu/drm/sti/sti_hqvdp.c
++++ b/drivers/gpu/drm/sti/sti_hqvdp.c
+@@ -1037,6 +1037,9 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane,
+ return 0;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
++ if (IS_ERR(crtc_state))
++ return PTR_ERR(crtc_state);
++
+ mode = &crtc_state->mode;
+ dst_x = new_plane_state->crtc_x;
+ dst_y = new_plane_state->crtc_y;
+diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c
+index 5a453532901f15..166d4a88daee5b 100644
+--- a/drivers/gpu/drm/v3d/v3d_mmu.c
++++ b/drivers/gpu/drm/v3d/v3d_mmu.c
+@@ -34,32 +34,23 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d)
+ {
+ int ret;
+
+- /* Make sure that another flush isn't already running when we
+- * start this one.
+- */
+- ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
+- V3D_MMU_CTL_TLB_CLEARING), 100);
+- if (ret)
+- dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n");
+-
+- V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
+- V3D_MMU_CTL_TLB_CLEAR);
+-
+- V3D_WRITE(V3D_MMUC_CONTROL,
+- V3D_MMUC_CONTROL_FLUSH |
++ V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_FLUSH |
+ V3D_MMUC_CONTROL_ENABLE);
+
+- ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
+- V3D_MMU_CTL_TLB_CLEARING), 100);
++ ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
++ V3D_MMUC_CONTROL_FLUSHING), 100);
+ if (ret) {
+- dev_err(v3d->drm.dev, "TLB clear wait idle failed\n");
++ dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
+ return ret;
+ }
+
+- ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
+- V3D_MMUC_CONTROL_FLUSHING), 100);
++ V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
++ V3D_MMU_CTL_TLB_CLEAR);
++
++ ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
++ V3D_MMU_CTL_TLB_CLEARING), 100);
+ if (ret)
+- dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
++ dev_err(v3d->drm.dev, "MMU TLB clear wait idle failed\n");
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
+index bf66499765fbb8..ac4ad95b364382 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -314,6 +314,7 @@ struct vc4_hvs {
+ struct platform_device *pdev;
+ void __iomem *regs;
+ u32 __iomem *dlist;
++ unsigned int dlist_mem_size;
+
+ struct clk *core_clk;
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index c6e986f71a26f8..d4487f4cb3034d 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -179,6 +179,8 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
+ if (!drm_dev_enter(drm, &idx))
+ return -ENODEV;
+
++ WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
++
+ drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
+ drm_print_regset32(&p, &vc4_hdmi->hd_regset);
+ drm_print_regset32(&p, &vc4_hdmi->cec_regset);
+@@ -188,6 +190,8 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
+ drm_print_regset32(&p, &vc4_hdmi->ram_regset);
+ drm_print_regset32(&p, &vc4_hdmi->rm_regset);
+
++ pm_runtime_put(&vc4_hdmi->pdev->dev);
++
+ drm_dev_exit(idx);
+
+ return 0;
+diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
+index 04af672caacb1b..008352166579ec 100644
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c
+@@ -110,7 +110,8 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data)
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_hvs *hvs = vc4->hvs;
+ struct drm_printer p = drm_seq_file_printer(m);
+- unsigned int next_entry_start = 0;
++ unsigned int dlist_mem_size = hvs->dlist_mem_size;
++ unsigned int next_entry_start;
+ unsigned int i, j;
+ u32 dlist_word, dispstat;
+
+@@ -124,8 +125,9 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data)
+ }
+
+ drm_printf(&p, "HVS chan %u:\n", i);
++ next_entry_start = 0;
+
+- for (j = HVS_READ(SCALER_DISPLISTX(i)); j < 256; j++) {
++ for (j = HVS_READ(SCALER_DISPLISTX(i)); j < dlist_mem_size; j++) {
+ dlist_word = readl((u32 __iomem *)vc4->hvs->dlist + j);
+ drm_printf(&p, "dlist: %02d: 0x%08x\n", j,
+ dlist_word);
+@@ -222,6 +224,9 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs,
+ if (!drm_dev_enter(drm, &idx))
+ return;
+
++ if (hvs->vc4->is_vc5)
++ return;
++
+ /* The LUT memory is laid out with each HVS channel in order,
+ * each of which takes 256 writes for R, 256 for G, then 256
+ * for B.
+@@ -415,13 +420,11 @@ void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int chan)
+ if (!drm_dev_enter(drm, &idx))
+ return;
+
+- if (HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE)
++ if (!(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE))
+ goto out;
+
+- HVS_WRITE(SCALER_DISPCTRLX(chan),
+- HVS_READ(SCALER_DISPCTRLX(chan)) | SCALER_DISPCTRLX_RESET);
+- HVS_WRITE(SCALER_DISPCTRLX(chan),
+- HVS_READ(SCALER_DISPCTRLX(chan)) & ~SCALER_DISPCTRLX_ENABLE);
++ HVS_WRITE(SCALER_DISPCTRLX(chan), SCALER_DISPCTRLX_RESET);
++ HVS_WRITE(SCALER_DISPCTRLX(chan), 0);
+
+ /* Once we leave, the scaler should be disabled and its fifo empty. */
+ WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET);
+@@ -580,7 +583,7 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
+ }
+
+ if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED)
+- return;
++ goto exit;
+
+ if (debug_dump_regs) {
+ DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
+@@ -663,6 +666,7 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
+ vc4_hvs_dump_state(hvs);
+ }
+
++exit:
+ drm_dev_exit(idx);
+ }
+
+@@ -800,9 +804,10 @@ struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pde
+ * our 16K), since we don't want to scramble the screen when
+ * transitioning from the firmware's boot setup to runtime.
+ */
++ hvs->dlist_mem_size = (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END;
+ drm_mm_init(&hvs->dlist_mm,
+ HVS_BOOTLOADER_DLIST_END,
+- (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END);
++ hvs->dlist_mem_size);
+
+ /* Set up the HVS LBM memory manager. We could have some more
+ * complicated data structure that allowed reuse of LBM areas
+diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
+index 5ce70dd946aa63..24589b947dea3d 100644
+--- a/drivers/gpu/drm/vkms/vkms_output.c
++++ b/drivers/gpu/drm/vkms/vkms_output.c
+@@ -84,7 +84,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index)
+ DRM_MODE_CONNECTOR_VIRTUAL);
+ if (ret) {
+ DRM_ERROR("Failed to init connector\n");
+- goto err_connector;
++ return ret;
+ }
+
+ drm_connector_helper_add(connector, &vkms_conn_helper_funcs);
+@@ -119,8 +119,5 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index)
+ err_encoder:
+ drm_connector_cleanup(connector);
+
+-err_connector:
+- drm_crtc_cleanup(crtc);
+-
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c
+index 44d4a510ad7d68..079bd97da4fa67 100644
+--- a/drivers/gpu/drm/xlnx/zynqmp_kms.c
++++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c
+@@ -506,12 +506,12 @@ int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
+ if (ret)
+ return ret;
+
+- drm_kms_helper_poll_init(drm);
+-
+ ret = zynqmp_dpsub_kms_init(dpsub);
+ if (ret < 0)
+ goto err_poll_fini;
+
++ drm_kms_helper_poll_init(drm);
++
+ /* Reset all components and register the DRM device. */
+ drm_mode_config_reset(drm);
+
+@@ -533,7 +533,7 @@ void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub)
+ {
+ struct drm_device *drm = &dpsub->drm->dev;
+
+- drm_dev_unregister(drm);
++ drm_dev_unplug(drm);
+ drm_atomic_helper_shutdown(drm);
+ drm_encoder_cleanup(&dpsub->drm->encoder);
+ drm_kms_helper_poll_fini(drm);
+diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
+index f33485d83d24ff..0fb210e40a4127 100644
+--- a/drivers/hid/hid-hyperv.c
++++ b/drivers/hid/hid-hyperv.c
+@@ -422,6 +422,25 @@ static int mousevsc_hid_raw_request(struct hid_device *hid,
+ return 0;
+ }
+
++static int mousevsc_hid_probe(struct hid_device *hid_dev, const struct hid_device_id *id)
++{
++ int ret;
++
++ ret = hid_parse(hid_dev);
++ if (ret) {
++ hid_err(hid_dev, "parse failed\n");
++ return ret;
++ }
++
++ ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV);
++ if (ret) {
++ hid_err(hid_dev, "hw start failed\n");
++ return ret;
++ }
++
++ return 0;
++}
++
+ static const struct hid_ll_driver mousevsc_ll_driver = {
+ .parse = mousevsc_hid_parse,
+ .open = mousevsc_hid_open,
+@@ -431,7 +450,16 @@ static const struct hid_ll_driver mousevsc_ll_driver = {
+ .raw_request = mousevsc_hid_raw_request,
+ };
+
+-static struct hid_driver mousevsc_hid_driver;
++static const struct hid_device_id mousevsc_devices[] = {
++ { HID_DEVICE(BUS_VIRTUAL, HID_GROUP_ANY, 0x045E, 0x0621) },
++ { }
++};
++
++static struct hid_driver mousevsc_hid_driver = {
++ .name = "hid-hyperv",
++ .id_table = mousevsc_devices,
++ .probe = mousevsc_hid_probe,
++};
+
+ static int mousevsc_probe(struct hv_device *device,
+ const struct hv_vmbus_device_id *dev_id)
+@@ -473,7 +501,6 @@ static int mousevsc_probe(struct hv_device *device,
+ }
+
+ hid_dev->ll_driver = &mousevsc_ll_driver;
+- hid_dev->driver = &mousevsc_hid_driver;
+ hid_dev->bus = BUS_VIRTUAL;
+ hid_dev->vendor = input_dev->hid_dev_info.vendor;
+ hid_dev->product = input_dev->hid_dev_info.product;
+@@ -488,20 +515,6 @@ static int mousevsc_probe(struct hv_device *device,
+ if (ret)
+ goto probe_err2;
+
+-
+- ret = hid_parse(hid_dev);
+- if (ret) {
+- hid_err(hid_dev, "parse failed\n");
+- goto probe_err2;
+- }
+-
+- ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV);
+-
+- if (ret) {
+- hid_err(hid_dev, "hw start failed\n");
+- goto probe_err2;
+- }
+-
+ device_init_wakeup(&device->device, true);
+
+ input_dev->connected = true;
+@@ -579,12 +592,23 @@ static struct hv_driver mousevsc_drv = {
+
+ static int __init mousevsc_init(void)
+ {
+- return vmbus_driver_register(&mousevsc_drv);
++ int ret;
++
++ ret = hid_register_driver(&mousevsc_hid_driver);
++ if (ret)
++ return ret;
++
++ ret = vmbus_driver_register(&mousevsc_drv);
++ if (ret)
++ hid_unregister_driver(&mousevsc_hid_driver);
++
++ return ret;
+ }
+
+ static void __exit mousevsc_exit(void)
+ {
+ vmbus_driver_unregister(&mousevsc_drv);
++ hid_unregister_driver(&mousevsc_hid_driver);
+ }
+
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index 18b5cd0234d213..33466c71c9da78 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -1399,9 +1399,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
+ rotation -= 1800;
+
+ input_report_abs(pen_input, ABS_TILT_X,
+- (char)frame[7]);
++ (signed char)frame[7]);
+ input_report_abs(pen_input, ABS_TILT_Y,
+- (char)frame[8]);
++ (signed char)frame[8]);
+ input_report_abs(pen_input, ABS_Z, rotation);
+ input_report_abs(pen_input, ABS_WHEEL,
+ get_unaligned_le16(&frame[11]));
+diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c
+index 8da7aa1614d7d1..16f6b7ba2a5def 100644
+--- a/drivers/hwmon/nct6775-core.c
++++ b/drivers/hwmon/nct6775-core.c
+@@ -2878,8 +2878,7 @@ store_target_temp(struct device *dev, struct device_attribute *attr,
+ if (err < 0)
+ return err;
+
+- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
+- data->target_temp_mask);
++ val = DIV_ROUND_CLOSEST(clamp_val(val, 0, data->target_temp_mask * 1000), 1000);
+
+ mutex_lock(&data->update_lock);
+ data->target_temp[nr] = val;
+@@ -2959,7 +2958,7 @@ store_temp_tolerance(struct device *dev, struct device_attribute *attr,
+ return err;
+
+ /* Limit tolerance as needed */
+- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
++ val = DIV_ROUND_CLOSEST(clamp_val(val, 0, data->tolerance_mask * 1000), 1000);
+
+ mutex_lock(&data->update_lock);
+ data->temp_tolerance[index][nr] = val;
+@@ -3085,7 +3084,7 @@ store_weight_temp(struct device *dev, struct device_attribute *attr,
+ if (err < 0)
+ return err;
+
+- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
++ val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000);
+
+ mutex_lock(&data->update_lock);
+ data->weight_temp[index][nr] = val;
+diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
+index 728c07c42651ce..019c5982ba564b 100644
+--- a/drivers/hwmon/pmbus/pmbus_core.c
++++ b/drivers/hwmon/pmbus/pmbus_core.c
+@@ -3199,7 +3199,17 @@ static int pmbus_regulator_notify(struct pmbus_data *data, int page, int event)
+
+ static int pmbus_write_smbalert_mask(struct i2c_client *client, u8 page, u8 reg, u8 val)
+ {
+- return pmbus_write_word_data(client, page, PMBUS_SMBALERT_MASK, reg | (val << 8));
++ int ret;
++
++ ret = _pmbus_write_word_data(client, page, PMBUS_SMBALERT_MASK, reg | (val << 8));
++
++ /*
++ * Clear fault systematically in case writing PMBUS_SMBALERT_MASK
++ * is not supported by the chip.
++ */
++ pmbus_clear_fault_page(client, page);
++
++ return ret;
+ }
+
+ static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
+diff --git a/drivers/hwmon/tps23861.c b/drivers/hwmon/tps23861.c
+index d33ecbac00d6d9..cea34fb9ba5829 100644
+--- a/drivers/hwmon/tps23861.c
++++ b/drivers/hwmon/tps23861.c
+@@ -132,7 +132,7 @@ static int tps23861_read_temp(struct tps23861_data *data, long *val)
+ if (err < 0)
+ return err;
+
+- *val = (regval * TEMPERATURE_LSB) - 20000;
++ *val = ((long)regval * TEMPERATURE_LSB) - 20000;
+
+ return 0;
+ }
+diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
+index 678b30e90492ad..5d4f04a3c6d322 100644
+--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
++++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
+@@ -99,6 +99,7 @@ struct lpi2c_imx_struct {
+ __u8 *rx_buf;
+ __u8 *tx_buf;
+ struct completion complete;
++ unsigned long rate_per;
+ unsigned int msglen;
+ unsigned int delivered;
+ unsigned int block_data;
+@@ -207,9 +208,7 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
+
+ lpi2c_imx_set_mode(lpi2c_imx);
+
+- clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk);
+- if (!clk_rate)
+- return -EINVAL;
++ clk_rate = lpi2c_imx->rate_per;
+
+ if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
+ filt = 0;
+@@ -590,6 +589,11 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
++ lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
++ if (!lpi2c_imx->rate_per)
++ return dev_err_probe(&pdev->dev, -EINVAL,
++ "can't get I2C peripheral clock rate\n");
++
+ pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_get_noresume(&pdev->dev);
+diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
+index 0e9ff5500a7771..70d120dfb0908f 100644
+--- a/drivers/i3c/master.c
++++ b/drivers/i3c/master.c
+@@ -1293,7 +1293,7 @@ static void i3c_master_put_i3c_addrs(struct i3c_dev_desc *dev)
+ I3C_ADDR_SLOT_FREE);
+
+ if (dev->boardinfo && dev->boardinfo->init_dyn_addr)
+- i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr,
++ i3c_bus_set_addr_slot_status(&master->bus, dev->boardinfo->init_dyn_addr,
+ I3C_ADDR_SLOT_FREE);
+ }
+
+diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
+index f344f8733f8324..dca266d9dd1220 100644
+--- a/drivers/i3c/master/svc-i3c-master.c
++++ b/drivers/i3c/master/svc-i3c-master.c
+@@ -1684,8 +1684,8 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
+ rpm_disable:
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+- pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_set_suspended(&pdev->dev);
+
+ err_disable_clks:
+ svc_i3c_master_unprepare_clks(master);
+diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c
+index 971fc60efef01b..220465d9c713fe 100644
+--- a/drivers/iio/accel/kionix-kx022a.c
++++ b/drivers/iio/accel/kionix-kx022a.c
+@@ -475,7 +475,7 @@ static int kx022a_get_axis(struct kx022a_data *data,
+ if (ret)
+ return ret;
+
+- *val = le16_to_cpu(data->buffer[0]);
++ *val = (s16)le16_to_cpu(data->buffer[0]);
+
+ return IIO_VAL_INT;
+ }
+diff --git a/drivers/iio/adc/ad7780.c b/drivers/iio/adc/ad7780.c
+index a813fe04787c60..97b6774e7f5856 100644
+--- a/drivers/iio/adc/ad7780.c
++++ b/drivers/iio/adc/ad7780.c
+@@ -152,7 +152,7 @@ static int ad7780_write_raw(struct iio_dev *indio_dev,
+
+ switch (m) {
+ case IIO_CHAN_INFO_SCALE:
+- if (val != 0)
++ if (val != 0 || val2 == 0)
+ return -EINVAL;
+
+ vref = st->int_vref_mv * 1000000LL;
+diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
+index 9d6bf6d0927a4b..709ce2a5009779 100644
+--- a/drivers/iio/adc/ad7923.c
++++ b/drivers/iio/adc/ad7923.c
+@@ -48,7 +48,7 @@
+
+ struct ad7923_state {
+ struct spi_device *spi;
+- struct spi_transfer ring_xfer[5];
++ struct spi_transfer ring_xfer[9];
+ struct spi_transfer scan_single_xfer[2];
+ struct spi_message ring_msg;
+ struct spi_message scan_single_msg;
+@@ -64,7 +64,7 @@ struct ad7923_state {
+ * Length = 8 channels + 4 extra for 8 byte timestamp
+ */
+ __be16 rx_buf[12] __aligned(IIO_DMA_MINALIGN);
+- __be16 tx_buf[4];
++ __be16 tx_buf[8];
+ };
+
+ struct ad7923_chip_info {
+diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c
+index 5f131bc1a01e97..291c0fc332c978 100644
+--- a/drivers/iio/industrialio-gts-helper.c
++++ b/drivers/iio/industrialio-gts-helper.c
+@@ -167,7 +167,7 @@ static int iio_gts_gain_cmp(const void *a, const void *b)
+
+ static int gain_to_scaletables(struct iio_gts *gts, int **gains, int **scales)
+ {
+- int ret, i, j, new_idx, time_idx;
++ int i, j, new_idx, time_idx, ret = 0;
+ int *all_gains;
+ size_t gain_bytes;
+
+@@ -205,7 +205,7 @@ static int gain_to_scaletables(struct iio_gts *gts, int **gains, int **scales)
+ memcpy(all_gains, gains[time_idx], gain_bytes);
+ new_idx = gts->num_hwgain;
+
+- while (time_idx--) {
++ while (time_idx-- > 0) {
+ for (j = 0; j < gts->num_hwgain; j++) {
+ int candidate = gains[time_idx][j];
+ int chk;
+diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
+index 80e1c45485c9b0..079e30c522bbd0 100644
+--- a/drivers/iio/inkern.c
++++ b/drivers/iio/inkern.c
+@@ -277,7 +277,7 @@ struct iio_channel *fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode,
+ return ERR_PTR(-ENODEV);
+ }
+
+- chan = __fwnode_iio_channel_get_by_name(fwnode, name);
++ chan = __fwnode_iio_channel_get_by_name(parent, name);
+ if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV) {
+ fwnode_handle_put(parent);
+ return chan;
+diff --git a/drivers/iio/light/al3010.c b/drivers/iio/light/al3010.c
+index 8f0119f392b705..7d4053bfceea2f 100644
+--- a/drivers/iio/light/al3010.c
++++ b/drivers/iio/light/al3010.c
+@@ -87,7 +87,12 @@ static int al3010_init(struct al3010_data *data)
+ int ret;
+
+ ret = al3010_set_pwr(data->client, true);
++ if (ret < 0)
++ return ret;
+
++ ret = devm_add_action_or_reset(&data->client->dev,
++ al3010_set_pwr_off,
++ data);
+ if (ret < 0)
+ return ret;
+
+@@ -190,12 +195,6 @@ static int al3010_probe(struct i2c_client *client)
+ return ret;
+ }
+
+- ret = devm_add_action_or_reset(&client->dev,
+- al3010_set_pwr_off,
+- data);
+- if (ret < 0)
+- return ret;
+-
+ return devm_iio_device_register(&client->dev, indio_dev);
+ }
+
+diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+index f20da108fb2978..df589726060144 100644
+--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+@@ -3559,7 +3559,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp,
+ wc->byte_len = orig_cqe->length;
+ wc->qp = &gsi_qp->ib_qp;
+
+- wc->ex.imm_data = cpu_to_be32(le32_to_cpu(orig_cqe->immdata));
++ wc->ex.imm_data = cpu_to_be32(orig_cqe->immdata);
+ wc->src_qp = orig_cqe->src_qp;
+ memcpy(wc->smac, orig_cqe->smac, ETH_ALEN);
+ if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) {
+@@ -3704,7 +3704,10 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
+ (unsigned long)(cqe->qp_handle),
+ struct bnxt_re_qp, qplib_qp);
+ wc->qp = &qp->ib_qp;
+- wc->ex.imm_data = cpu_to_be32(le32_to_cpu(cqe->immdata));
++ if (cqe->flags & CQ_RES_RC_FLAGS_IMM)
++ wc->ex.imm_data = cpu_to_be32(cqe->immdata);
++ else
++ wc->ex.invalidate_rkey = cqe->invrkey;
+ wc->src_qp = cqe->src_qp;
+ memcpy(wc->smac, cqe->smac, ETH_ALEN);
+ wc->port_num = 1;
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+index 56ddff96b5083b..5d4c49089a20f4 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+@@ -389,7 +389,7 @@ struct bnxt_qplib_cqe {
+ u16 cfa_meta;
+ u64 wr_id;
+ union {
+- __le32 immdata;
++ u32 immdata;
+ u32 invrkey;
+ };
+ u64 qp_handle;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c
+index ff177466de9b49..9b91731a620795 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
++++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
+@@ -180,8 +180,8 @@ static void free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
+ ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_CQC,
+ hr_cq->cqn);
+ if (ret)
+- dev_err(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n", ret,
+- hr_cq->cqn);
++ dev_err_ratelimited(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n",
++ ret, hr_cq->cqn);
+
+ xa_erase_irq(&cq_table->array, hr_cq->cqn);
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
+index cd593d651e4caf..21ef00fdb65631 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_device.h
++++ b/drivers/infiniband/hw/hns/hns_roce_device.h
+@@ -1236,6 +1236,7 @@ void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn);
+ void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type);
+ void flush_cqe(struct hns_roce_dev *dev, struct hns_roce_qp *qp);
+ void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type);
++void hns_roce_flush_cqe(struct hns_roce_dev *hr_dev, u32 qpn);
+ void hns_roce_srq_event(struct hns_roce_dev *hr_dev, u32 srqn, int event_type);
+ void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev);
+ int hns_roce_init(struct hns_roce_dev *hr_dev);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 7ebf80504fd125..0ab514c49d5e6e 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -337,7 +337,7 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev,
+ struct hns_roce_hem_mhop *mhop,
+ struct hns_roce_hem_index *index)
+ {
+- struct ib_device *ibdev = &hr_dev->ib_dev;
++ struct device *dev = hr_dev->dev;
+ unsigned long mhop_obj = obj;
+ u32 l0_idx, l1_idx, l2_idx;
+ u32 chunk_ba_num;
+@@ -368,14 +368,14 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev,
+ index->buf = l0_idx;
+ break;
+ default:
+- ibdev_err(ibdev, "table %u not support mhop.hop_num = %u!\n",
+- table->type, mhop->hop_num);
++ dev_err(dev, "table %u not support mhop.hop_num = %u!\n",
++ table->type, mhop->hop_num);
+ return -EINVAL;
+ }
+
+ if (unlikely(index->buf >= table->num_hem)) {
+- ibdev_err(ibdev, "table %u exceed hem limt idx %llu, max %lu!\n",
+- table->type, index->buf, table->num_hem);
++ dev_err(dev, "table %u exceed hem limt idx %llu, max %lu!\n",
++ table->type, index->buf, table->num_hem);
+ return -EINVAL;
+ }
+
+@@ -487,14 +487,14 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,
+ struct hns_roce_hem_mhop *mhop,
+ struct hns_roce_hem_index *index)
+ {
+- struct ib_device *ibdev = &hr_dev->ib_dev;
++ struct device *dev = hr_dev->dev;
+ u32 step_idx;
+ int ret = 0;
+
+ if (index->inited & HEM_INDEX_L0) {
+ ret = hr_dev->hw->set_hem(hr_dev, table, obj, 0);
+ if (ret) {
+- ibdev_err(ibdev, "set HEM step 0 failed!\n");
++ dev_err(dev, "set HEM step 0 failed!\n");
+ goto out;
+ }
+ }
+@@ -502,7 +502,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,
+ if (index->inited & HEM_INDEX_L1) {
+ ret = hr_dev->hw->set_hem(hr_dev, table, obj, 1);
+ if (ret) {
+- ibdev_err(ibdev, "set HEM step 1 failed!\n");
++ dev_err(dev, "set HEM step 1 failed!\n");
+ goto out;
+ }
+ }
+@@ -514,7 +514,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,
+ step_idx = mhop->hop_num;
+ ret = hr_dev->hw->set_hem(hr_dev, table, obj, step_idx);
+ if (ret)
+- ibdev_err(ibdev, "set HEM step last failed!\n");
++ dev_err(dev, "set HEM step last failed!\n");
+ }
+ out:
+ return ret;
+@@ -524,14 +524,14 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
+ struct hns_roce_hem_table *table,
+ unsigned long obj)
+ {
+- struct ib_device *ibdev = &hr_dev->ib_dev;
+ struct hns_roce_hem_index index = {};
+ struct hns_roce_hem_mhop mhop = {};
++ struct device *dev = hr_dev->dev;
+ int ret;
+
+ ret = calc_hem_config(hr_dev, table, obj, &mhop, &index);
+ if (ret) {
+- ibdev_err(ibdev, "calc hem config failed!\n");
++ dev_err(dev, "calc hem config failed!\n");
+ return ret;
+ }
+
+@@ -543,7 +543,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
+
+ ret = alloc_mhop_hem(hr_dev, table, &mhop, &index);
+ if (ret) {
+- ibdev_err(ibdev, "alloc mhop hem failed!\n");
++ dev_err(dev, "alloc mhop hem failed!\n");
+ goto out;
+ }
+
+@@ -551,7 +551,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
+ if (table->type < HEM_TYPE_MTT) {
+ ret = set_mhop_hem(hr_dev, table, obj, &mhop, &index);
+ if (ret) {
+- ibdev_err(ibdev, "set HEM address to HW failed!\n");
++ dev_err(dev, "set HEM address to HW failed!\n");
+ goto err_alloc;
+ }
+ }
+@@ -615,7 +615,7 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev,
+ struct hns_roce_hem_mhop *mhop,
+ struct hns_roce_hem_index *index)
+ {
+- struct ib_device *ibdev = &hr_dev->ib_dev;
++ struct device *dev = hr_dev->dev;
+ u32 hop_num = mhop->hop_num;
+ u32 chunk_ba_num;
+ u32 step_idx;
+@@ -645,21 +645,21 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev,
+
+ ret = hr_dev->hw->clear_hem(hr_dev, table, obj, step_idx);
+ if (ret)
+- ibdev_warn(ibdev, "failed to clear hop%u HEM, ret = %d.\n",
+- hop_num, ret);
++ dev_warn(dev, "failed to clear hop%u HEM, ret = %d.\n",
++ hop_num, ret);
+
+ if (index->inited & HEM_INDEX_L1) {
+ ret = hr_dev->hw->clear_hem(hr_dev, table, obj, 1);
+ if (ret)
+- ibdev_warn(ibdev, "failed to clear HEM step 1, ret = %d.\n",
+- ret);
++ dev_warn(dev, "failed to clear HEM step 1, ret = %d.\n",
++ ret);
+ }
+
+ if (index->inited & HEM_INDEX_L0) {
+ ret = hr_dev->hw->clear_hem(hr_dev, table, obj, 0);
+ if (ret)
+- ibdev_warn(ibdev, "failed to clear HEM step 0, ret = %d.\n",
+- ret);
++ dev_warn(dev, "failed to clear HEM step 0, ret = %d.\n",
++ ret);
+ }
+ }
+ }
+@@ -669,14 +669,14 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
+ unsigned long obj,
+ int check_refcount)
+ {
+- struct ib_device *ibdev = &hr_dev->ib_dev;
+ struct hns_roce_hem_index index = {};
+ struct hns_roce_hem_mhop mhop = {};
++ struct device *dev = hr_dev->dev;
+ int ret;
+
+ ret = calc_hem_config(hr_dev, table, obj, &mhop, &index);
+ if (ret) {
+- ibdev_err(ibdev, "calc hem config failed!\n");
++ dev_err(dev, "calc hem config failed!\n");
+ return;
+ }
+
+@@ -712,8 +712,8 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
+
+ ret = hr_dev->hw->clear_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT);
+ if (ret)
+- dev_warn(dev, "failed to clear HEM base address, ret = %d.\n",
+- ret);
++ dev_warn_ratelimited(dev, "failed to clear HEM base address, ret = %d.\n",
++ ret);
+
+ hns_roce_free_hem(hr_dev, table->hem[i]);
+ table->hem[i] = NULL;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 8066750afab908..2824d390ec3161 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -372,19 +372,12 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr,
+ static int check_send_valid(struct hns_roce_dev *hr_dev,
+ struct hns_roce_qp *hr_qp)
+ {
+- struct ib_device *ibdev = &hr_dev->ib_dev;
+-
+ if (unlikely(hr_qp->state == IB_QPS_RESET ||
+ hr_qp->state == IB_QPS_INIT ||
+- hr_qp->state == IB_QPS_RTR)) {
+- ibdev_err(ibdev, "failed to post WQE, QP state %u!\n",
+- hr_qp->state);
++ hr_qp->state == IB_QPS_RTR))
+ return -EINVAL;
+- } else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN)) {
+- ibdev_err(ibdev, "failed to post WQE, dev state %d!\n",
+- hr_dev->state);
++ else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN))
+ return -EIO;
+- }
+
+ return 0;
+ }
+@@ -585,7 +578,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,
+ if (WARN_ON(ret))
+ return ret;
+
+- hr_reg_write(rc_sq_wqe, RC_SEND_WQE_FENCE,
++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SO,
+ (wr->send_flags & IB_SEND_FENCE) ? 1 : 0);
+
+ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SE,
+@@ -2737,8 +2730,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
+ ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT,
+ IB_QPS_INIT, NULL);
+ if (ret) {
+- ibdev_err(ibdev, "failed to modify qp to init, ret = %d.\n",
+- ret);
++ ibdev_err_ratelimited(ibdev, "failed to modify qp to init, ret = %d.\n",
++ ret);
+ return ret;
+ }
+
+@@ -3384,8 +3377,8 @@ static int free_mr_post_send_lp_wqe(struct hns_roce_qp *hr_qp)
+
+ ret = hns_roce_v2_post_send(&hr_qp->ibqp, send_wr, &bad_wr);
+ if (ret) {
+- ibdev_err(ibdev, "failed to post wqe for free mr, ret = %d.\n",
+- ret);
++ ibdev_err_ratelimited(ibdev, "failed to post wqe for free mr, ret = %d.\n",
++ ret);
+ return ret;
+ }
+
+@@ -3424,9 +3417,9 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
+
+ ret = free_mr_post_send_lp_wqe(hr_qp);
+ if (ret) {
+- ibdev_err(ibdev,
+- "failed to send wqe (qp:0x%lx) for free mr, ret = %d.\n",
+- hr_qp->qpn, ret);
++ ibdev_err_ratelimited(ibdev,
++ "failed to send wqe (qp:0x%lx) for free mr, ret = %d.\n",
++ hr_qp->qpn, ret);
+ break;
+ }
+
+@@ -3437,16 +3430,16 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
+ while (cqe_cnt) {
+ npolled = hns_roce_v2_poll_cq(&free_mr->rsv_cq->ib_cq, cqe_cnt, wc);
+ if (npolled < 0) {
+- ibdev_err(ibdev,
+- "failed to poll cqe for free mr, remain %d cqe.\n",
+- cqe_cnt);
++ ibdev_err_ratelimited(ibdev,
++ "failed to poll cqe for free mr, remain %d cqe.\n",
++ cqe_cnt);
+ goto out;
+ }
+
+ if (time_after(jiffies, end)) {
+- ibdev_err(ibdev,
+- "failed to poll cqe for free mr and timeout, remain %d cqe.\n",
+- cqe_cnt);
++ ibdev_err_ratelimited(ibdev,
++ "failed to poll cqe for free mr and timeout, remain %d cqe.\n",
++ cqe_cnt);
+ goto out;
+ }
+ cqe_cnt -= npolled;
+@@ -4986,10 +4979,8 @@ static int hns_roce_v2_set_abs_fields(struct ib_qp *ibqp,
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ int ret = 0;
+
+- if (!check_qp_state(cur_state, new_state)) {
+- ibdev_err(&hr_dev->ib_dev, "Illegal state for QP!\n");
++ if (!check_qp_state(cur_state, new_state))
+ return -EINVAL;
+- }
+
+ if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+ memset(qpc_mask, 0, hr_dev->caps.qpc_sz);
+@@ -5251,7 +5242,7 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp,
+ /* SW pass context to HW */
+ ret = hns_roce_v2_qp_modify(hr_dev, context, qpc_mask, hr_qp);
+ if (ret) {
+- ibdev_err(ibdev, "failed to modify QP, ret = %d.\n", ret);
++ ibdev_err_ratelimited(ibdev, "failed to modify QP, ret = %d.\n", ret);
+ goto out;
+ }
+
+@@ -5341,7 +5332,9 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+
+ ret = hns_roce_v2_query_qpc(hr_dev, hr_qp->qpn, &context);
+ if (ret) {
+- ibdev_err(ibdev, "failed to query QPC, ret = %d.\n", ret);
++ ibdev_err_ratelimited(ibdev,
++ "failed to query QPC, ret = %d.\n",
++ ret);
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -5349,7 +5342,7 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ state = hr_reg_read(&context, QPC_QP_ST);
+ tmp_qp_state = to_ib_qp_st((enum hns_roce_v2_qp_state)state);
+ if (tmp_qp_state == -1) {
+- ibdev_err(ibdev, "Illegal ib_qp_state\n");
++ ibdev_err_ratelimited(ibdev, "Illegal ib_qp_state\n");
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -5442,9 +5435,9 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
+ ret = hns_roce_v2_modify_qp(&hr_qp->ibqp, NULL, 0,
+ hr_qp->state, IB_QPS_RESET, udata);
+ if (ret)
+- ibdev_err(ibdev,
+- "failed to modify QP to RST, ret = %d.\n",
+- ret);
++ ibdev_err_ratelimited(ibdev,
++ "failed to modify QP to RST, ret = %d.\n",
++ ret);
+ }
+
+ send_cq = hr_qp->ibqp.send_cq ? to_hr_cq(hr_qp->ibqp.send_cq) : NULL;
+@@ -5480,9 +5473,9 @@ int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
+
+ ret = hns_roce_v2_destroy_qp_common(hr_dev, hr_qp, udata);
+ if (ret)
+- ibdev_err(&hr_dev->ib_dev,
+- "failed to destroy QP, QPN = 0x%06lx, ret = %d.\n",
+- hr_qp->qpn, ret);
++ ibdev_err_ratelimited(&hr_dev->ib_dev,
++ "failed to destroy QP, QPN = 0x%06lx, ret = %d.\n",
++ hr_qp->qpn, ret);
+
+ hns_roce_qp_destroy(hr_dev, hr_qp, udata);
+
+@@ -5755,9 +5748,9 @@ static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
+ HNS_ROCE_CMD_MODIFY_CQC, hr_cq->cqn);
+ hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+ if (ret)
+- ibdev_err(&hr_dev->ib_dev,
+- "failed to process cmd when modifying CQ, ret = %d.\n",
+- ret);
++ ibdev_err_ratelimited(&hr_dev->ib_dev,
++ "failed to process cmd when modifying CQ, ret = %d.\n",
++ ret);
+
+ return ret;
+ }
+@@ -5777,9 +5770,9 @@ static int hns_roce_v2_query_cqc(struct hns_roce_dev *hr_dev, u32 cqn,
+ ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma,
+ HNS_ROCE_CMD_QUERY_CQC, cqn);
+ if (ret) {
+- ibdev_err(&hr_dev->ib_dev,
+- "failed to process cmd when querying CQ, ret = %d.\n",
+- ret);
++ ibdev_err_ratelimited(&hr_dev->ib_dev,
++ "failed to process cmd when querying CQ, ret = %d.\n",
++ ret);
+ goto err_mailbox;
+ }
+
+@@ -5820,11 +5813,10 @@ static int hns_roce_v2_query_mpt(struct hns_roce_dev *hr_dev, u32 key,
+ return ret;
+ }
+
+-static void hns_roce_irq_work_handle(struct work_struct *work)
++static void dump_aeqe_log(struct hns_roce_work *irq_work)
+ {
+- struct hns_roce_work *irq_work =
+- container_of(work, struct hns_roce_work, work);
+- struct ib_device *ibdev = &irq_work->hr_dev->ib_dev;
++ struct hns_roce_dev *hr_dev = irq_work->hr_dev;
++ struct ib_device *ibdev = &hr_dev->ib_dev;
+
+ switch (irq_work->event_type) {
+ case HNS_ROCE_EVENT_TYPE_PATH_MIG:
+@@ -5868,6 +5860,8 @@ static void hns_roce_irq_work_handle(struct work_struct *work)
+ case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
+ ibdev_warn(ibdev, "DB overflow.\n");
+ break;
++ case HNS_ROCE_EVENT_TYPE_MB:
++ break;
+ case HNS_ROCE_EVENT_TYPE_FLR:
+ ibdev_warn(ibdev, "function level reset.\n");
+ break;
+@@ -5877,10 +5871,48 @@ static void hns_roce_irq_work_handle(struct work_struct *work)
+ case HNS_ROCE_EVENT_TYPE_INVALID_XRCETH:
+ ibdev_err(ibdev, "invalid xrceth error.\n");
+ break;
++ default:
++ ibdev_info(ibdev, "Undefined event %d.\n",
++ irq_work->event_type);
++ break;
++ }
++}
++
++static void hns_roce_irq_work_handle(struct work_struct *work)
++{
++ struct hns_roce_work *irq_work =
++ container_of(work, struct hns_roce_work, work);
++ struct hns_roce_dev *hr_dev = irq_work->hr_dev;
++ int event_type = irq_work->event_type;
++ u32 queue_num = irq_work->queue_num;
++
++ switch (event_type) {
++ case HNS_ROCE_EVENT_TYPE_PATH_MIG:
++ case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
++ case HNS_ROCE_EVENT_TYPE_COMM_EST:
++ case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
++ case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
++ case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
++ case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
++ case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
++ case HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION:
++ case HNS_ROCE_EVENT_TYPE_INVALID_XRCETH:
++ hns_roce_qp_event(hr_dev, queue_num, event_type);
++ break;
++ case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
++ case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
++ hns_roce_srq_event(hr_dev, queue_num, event_type);
++ break;
++ case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
++ case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
++ hns_roce_cq_event(hr_dev, queue_num, event_type);
++ break;
+ default:
+ break;
+ }
+
++ dump_aeqe_log(irq_work);
++
+ kfree(irq_work);
+ }
+
+@@ -5940,14 +5972,14 @@ static struct hns_roce_aeqe *next_aeqe_sw_v2(struct hns_roce_eq *eq)
+ static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+ struct hns_roce_eq *eq)
+ {
+- struct device *dev = hr_dev->dev;
+ struct hns_roce_aeqe *aeqe = next_aeqe_sw_v2(eq);
+ irqreturn_t aeqe_found = IRQ_NONE;
++ int num_aeqes = 0;
+ int event_type;
+ u32 queue_num;
+ int sub_type;
+
+- while (aeqe) {
++ while (aeqe && num_aeqes < HNS_AEQ_POLLING_BUDGET) {
+ /* Make sure we read AEQ entry after we have checked the
+ * ownership bit
+ */
+@@ -5958,25 +5990,12 @@ static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+ queue_num = hr_reg_read(aeqe, AEQE_EVENT_QUEUE_NUM);
+
+ switch (event_type) {
+- case HNS_ROCE_EVENT_TYPE_PATH_MIG:
+- case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
+- case HNS_ROCE_EVENT_TYPE_COMM_EST:
+- case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
+ case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+- case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
+ case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
+ case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
+ case HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION:
+ case HNS_ROCE_EVENT_TYPE_INVALID_XRCETH:
+- hns_roce_qp_event(hr_dev, queue_num, event_type);
+- break;
+- case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
+- case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
+- hns_roce_srq_event(hr_dev, queue_num, event_type);
+- break;
+- case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
+- case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
+- hns_roce_cq_event(hr_dev, queue_num, event_type);
++ hns_roce_flush_cqe(hr_dev, queue_num);
+ break;
+ case HNS_ROCE_EVENT_TYPE_MB:
+ hns_roce_cmd_event(hr_dev,
+@@ -5984,12 +6003,7 @@ static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+ aeqe->event.cmd.status,
+ le64_to_cpu(aeqe->event.cmd.out_param));
+ break;
+- case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
+- case HNS_ROCE_EVENT_TYPE_FLR:
+- break;
+ default:
+- dev_err(dev, "unhandled event %d on EQ %d at idx %u.\n",
+- event_type, eq->eqn, eq->cons_index);
+ break;
+ }
+
+@@ -6001,6 +6015,7 @@ static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+ hns_roce_v2_init_irq_work(hr_dev, eq, queue_num);
+
+ aeqe = next_aeqe_sw_v2(eq);
++ ++num_aeqes;
+ }
+
+ update_eq_db(eq);
+@@ -6530,6 +6545,9 @@ static int hns_roce_v2_init_eq_table(struct hns_roce_dev *hr_dev)
+ int ret;
+ int i;
+
++ if (hr_dev->caps.aeqe_depth < HNS_AEQ_POLLING_BUDGET)
++ return -EINVAL;
++
+ other_num = hr_dev->caps.num_other_vectors;
+ comp_num = hr_dev->caps.num_comp_vectors;
+ aeq_num = hr_dev->caps.num_aeq_vectors;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index cd97cbee682a6a..b8e17721f6fdea 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -85,6 +85,11 @@
+
+ #define HNS_ROCE_V2_TABLE_CHUNK_SIZE (1 << 18)
+
++/* budget must be smaller than aeqe_depth to guarantee that we update
++ * the ci before we polled all the entries in the EQ.
++ */
++#define HNS_AEQ_POLLING_BUDGET 64
++
+ enum {
+ HNS_ROCE_CMD_FLAG_IN = BIT(0),
+ HNS_ROCE_CMD_FLAG_OUT = BIT(1),
+@@ -894,6 +899,7 @@ struct hns_roce_v2_rc_send_wqe {
+ #define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7)
+ #define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8)
+ #define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9)
++#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10)
+ #define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11)
+ #define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12)
+ #define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15)
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index 980261969b0c0a..7f29a55d378f02 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -130,8 +130,8 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr
+ key_to_hw_index(mr->key) &
+ (hr_dev->caps.num_mtpts - 1));
+ if (ret)
+- ibdev_warn(ibdev, "failed to destroy mpt, ret = %d.\n",
+- ret);
++ ibdev_warn_ratelimited(ibdev, "failed to destroy mpt, ret = %d.\n",
++ ret);
+ }
+
+ free_mr_pbl(hr_dev, mr);
+@@ -415,15 +415,16 @@ static int hns_roce_set_page(struct ib_mr *ibmr, u64 addr)
+ }
+
+ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
+- unsigned int *sg_offset)
++ unsigned int *sg_offset_p)
+ {
++ unsigned int sg_offset = sg_offset_p ? *sg_offset_p : 0;
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
+ struct ib_device *ibdev = &hr_dev->ib_dev;
+ struct hns_roce_mr *mr = to_hr_mr(ibmr);
+ struct hns_roce_mtr *mtr = &mr->pbl_mtr;
+ int ret, sg_num = 0;
+
+- if (!IS_ALIGNED(*sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) ||
++ if (!IS_ALIGNED(sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) ||
+ ibmr->page_size < HNS_HW_PAGE_SIZE ||
+ ibmr->page_size > HNS_HW_MAX_PAGE_SIZE)
+ return sg_num;
+@@ -434,7 +435,7 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
+ if (!mr->page_list)
+ return sg_num;
+
+- sg_num = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, hns_roce_set_page);
++ sg_num = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset_p, hns_roce_set_page);
+ if (sg_num < 1) {
+ ibdev_err(ibdev, "failed to store sg pages %u %u, cnt = %d.\n",
+ mr->npages, mr->pbl_mtr.hem_cfg.buf_pg_count, sg_num);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
+index 04063cfacae5fc..88a4777d29f8b8 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -39,6 +39,25 @@
+ #include "hns_roce_device.h"
+ #include "hns_roce_hem.h"
+
++static struct hns_roce_qp *hns_roce_qp_lookup(struct hns_roce_dev *hr_dev,
++ u32 qpn)
++{
++ struct device *dev = hr_dev->dev;
++ struct hns_roce_qp *qp;
++ unsigned long flags;
++
++ xa_lock_irqsave(&hr_dev->qp_table_xa, flags);
++ qp = __hns_roce_qp_lookup(hr_dev, qpn);
++ if (qp)
++ refcount_inc(&qp->refcount);
++ xa_unlock_irqrestore(&hr_dev->qp_table_xa, flags);
++
++ if (!qp)
++ dev_warn(dev, "async event for bogus QP %08x\n", qpn);
++
++ return qp;
++}
++
+ static void flush_work_handle(struct work_struct *work)
+ {
+ struct hns_roce_work *flush_work = container_of(work,
+@@ -95,31 +114,28 @@ void flush_cqe(struct hns_roce_dev *dev, struct hns_roce_qp *qp)
+
+ void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
+ {
+- struct device *dev = hr_dev->dev;
+ struct hns_roce_qp *qp;
+
+- xa_lock(&hr_dev->qp_table_xa);
+- qp = __hns_roce_qp_lookup(hr_dev, qpn);
+- if (qp)
+- refcount_inc(&qp->refcount);
+- xa_unlock(&hr_dev->qp_table_xa);
+-
+- if (!qp) {
+- dev_warn(dev, "async event for bogus QP %08x\n", qpn);
++ qp = hns_roce_qp_lookup(hr_dev, qpn);
++ if (!qp)
+ return;
+- }
+
+- if (event_type == HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR ||
+- event_type == HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR ||
+- event_type == HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR ||
+- event_type == HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION ||
+- event_type == HNS_ROCE_EVENT_TYPE_INVALID_XRCETH) {
+- qp->state = IB_QPS_ERR;
++ qp->event(qp, (enum hns_roce_event)event_type);
+
+- flush_cqe(hr_dev, qp);
+- }
++ if (refcount_dec_and_test(&qp->refcount))
++ complete(&qp->free);
++}
+
+- qp->event(qp, (enum hns_roce_event)event_type);
++void hns_roce_flush_cqe(struct hns_roce_dev *hr_dev, u32 qpn)
++{
++ struct hns_roce_qp *qp;
++
++ qp = hns_roce_qp_lookup(hr_dev, qpn);
++ if (!qp)
++ return;
++
++ qp->state = IB_QPS_ERR;
++ flush_cqe(hr_dev, qp);
+
+ if (refcount_dec_and_test(&qp->refcount))
+ complete(&qp->free);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c
+index 727f926500712c..652508b660a060 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_srq.c
++++ b/drivers/infiniband/hw/hns/hns_roce_srq.c
+@@ -150,8 +150,8 @@ static void free_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq)
+ ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_SRQ,
+ srq->srqn);
+ if (ret)
+- dev_err(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n",
+- ret, srq->srqn);
++ dev_err_ratelimited(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n",
++ ret, srq->srqn);
+
+ xa_erase_irq(&srq_table->xa, srq->srqn);
+
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index 296af7a5c2794d..c510484e024b1a 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -2796,37 +2796,72 @@ static u8 mlx5_get_umr_fence(u8 umr_fence_cap)
+ }
+ }
+
+-static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
++int mlx5_ib_dev_res_cq_init(struct mlx5_ib_dev *dev)
+ {
+ struct mlx5_ib_resources *devr = &dev->devr;
+- struct ib_srq_init_attr attr;
+- struct ib_device *ibdev;
+ struct ib_cq_init_attr cq_attr = {.cqe = 1};
+- int port;
++ struct ib_device *ibdev;
++ struct ib_pd *pd;
++ struct ib_cq *cq;
+ int ret = 0;
+
+- ibdev = &dev->ib_dev;
+
+- if (!MLX5_CAP_GEN(dev->mdev, xrc))
+- return -EOPNOTSUPP;
++ /*
++ * devr->c0 is set once, never changed until device unload.
++ * Avoid taking the mutex if initialization is already done.
++ */
++ if (devr->c0)
++ return 0;
+
+- devr->p0 = ib_alloc_pd(ibdev, 0);
+- if (IS_ERR(devr->p0))
+- return PTR_ERR(devr->p0);
++ mutex_lock(&devr->cq_lock);
++ if (devr->c0)
++ goto unlock;
+
+- devr->c0 = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr);
+- if (IS_ERR(devr->c0)) {
+- ret = PTR_ERR(devr->c0);
+- goto error1;
++ ibdev = &dev->ib_dev;
++ pd = ib_alloc_pd(ibdev, 0);
++ if (IS_ERR(pd)) {
++ ret = PTR_ERR(pd);
++ mlx5_ib_err(dev, "Couldn't allocate PD for res init, err=%d\n", ret);
++ goto unlock;
+ }
+
+- ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0);
+- if (ret)
+- goto error2;
++ cq = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr);
++ if (IS_ERR(cq)) {
++ ret = PTR_ERR(cq);
++ mlx5_ib_err(dev, "Couldn't create CQ for res init, err=%d\n", ret);
++ ib_dealloc_pd(pd);
++ goto unlock;
++ }
+
+- ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn1, 0);
++ devr->p0 = pd;
++ devr->c0 = cq;
++
++unlock:
++ mutex_unlock(&devr->cq_lock);
++ return ret;
++}
++
++int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev)
++{
++ struct mlx5_ib_resources *devr = &dev->devr;
++ struct ib_srq_init_attr attr;
++ struct ib_srq *s0, *s1;
++ int ret = 0;
++
++ /*
++ * devr->s1 is set once, never changed until device unload.
++ * Avoid taking the mutex if initialization is already done.
++ */
++ if (devr->s1)
++ return 0;
++
++ mutex_lock(&devr->srq_lock);
++ if (devr->s1)
++ goto unlock;
++
++ ret = mlx5_ib_dev_res_cq_init(dev);
+ if (ret)
+- goto error3;
++ goto unlock;
+
+ memset(&attr, 0, sizeof(attr));
+ attr.attr.max_sge = 1;
+@@ -2834,10 +2869,11 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
+ attr.srq_type = IB_SRQT_XRC;
+ attr.ext.cq = devr->c0;
+
+- devr->s0 = ib_create_srq(devr->p0, &attr);
+- if (IS_ERR(devr->s0)) {
+- ret = PTR_ERR(devr->s0);
+- goto err_create;
++ s0 = ib_create_srq(devr->p0, &attr);
++ if (IS_ERR(s0)) {
++ ret = PTR_ERR(s0);
++ mlx5_ib_err(dev, "Couldn't create SRQ 0 for res init, err=%d\n", ret);
++ goto unlock;
+ }
+
+ memset(&attr, 0, sizeof(attr));
+@@ -2845,51 +2881,63 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
+ attr.attr.max_wr = 1;
+ attr.srq_type = IB_SRQT_BASIC;
+
+- devr->s1 = ib_create_srq(devr->p0, &attr);
+- if (IS_ERR(devr->s1)) {
+- ret = PTR_ERR(devr->s1);
+- goto error6;
++ s1 = ib_create_srq(devr->p0, &attr);
++ if (IS_ERR(s1)) {
++ ret = PTR_ERR(s1);
++ mlx5_ib_err(dev, "Couldn't create SRQ 1 for res init, err=%d\n", ret);
++ ib_destroy_srq(s0);
+ }
+
+- for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
+- INIT_WORK(&devr->ports[port].pkey_change_work,
+- pkey_change_handler);
+-
+- return 0;
++ devr->s0 = s0;
++ devr->s1 = s1;
+
+-error6:
+- ib_destroy_srq(devr->s0);
+-err_create:
+- mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
+-error3:
+- mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
+-error2:
+- ib_destroy_cq(devr->c0);
+-error1:
+- ib_dealloc_pd(devr->p0);
++unlock:
++ mutex_unlock(&devr->srq_lock);
+ return ret;
+ }
+
+-static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
++static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
+ {
+ struct mlx5_ib_resources *devr = &dev->devr;
+- int port;
++ int ret;
+
+- /*
+- * Make sure no change P_Key work items are still executing.
+- *
+- * At this stage, the mlx5_ib_event should be unregistered
+- * and it ensures that no new works are added.
+- */
+- for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
+- cancel_work_sync(&devr->ports[port].pkey_change_work);
++ if (!MLX5_CAP_GEN(dev->mdev, xrc))
++ return -EOPNOTSUPP;
++
++ ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0);
++ if (ret)
++ return ret;
++
++ ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn1, 0);
++ if (ret) {
++ mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
++ return ret;
++ }
++
++ mutex_init(&devr->cq_lock);
++ mutex_init(&devr->srq_lock);
+
+- ib_destroy_srq(devr->s1);
+- ib_destroy_srq(devr->s0);
++ return 0;
++}
++
++static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
++{
++ struct mlx5_ib_resources *devr = &dev->devr;
++
++ /* After s0/s1 init, they are not unset during the device lifetime. */
++ if (devr->s1) {
++ ib_destroy_srq(devr->s1);
++ ib_destroy_srq(devr->s0);
++ }
+ mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
+ mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
+- ib_destroy_cq(devr->c0);
+- ib_dealloc_pd(devr->p0);
++ /* After p0/c0 init, they are not unset during the device lifetime. */
++ if (devr->c0) {
++ ib_destroy_cq(devr->c0);
++ ib_dealloc_pd(devr->p0);
++ }
++ mutex_destroy(&devr->cq_lock);
++ mutex_destroy(&devr->srq_lock);
+ }
+
+ static u32 get_core_cap_flags(struct ib_device *ibdev,
+@@ -4138,6 +4186,13 @@ static void mlx5_ib_stage_delay_drop_cleanup(struct mlx5_ib_dev *dev)
+
+ static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
+ {
++ struct mlx5_ib_resources *devr = &dev->devr;
++ int port;
++
++ for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
++ INIT_WORK(&devr->ports[port].pkey_change_work,
++ pkey_change_handler);
++
+ dev->mdev_events.notifier_call = mlx5_ib_event;
+ mlx5_notifier_register(dev->mdev, &dev->mdev_events);
+
+@@ -4148,8 +4203,14 @@ static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
+
+ static void mlx5_ib_stage_dev_notifier_cleanup(struct mlx5_ib_dev *dev)
+ {
++ struct mlx5_ib_resources *devr = &dev->devr;
++ int port;
++
+ mlx5r_macsec_event_unregister(dev);
+ mlx5_notifier_unregister(dev->mdev, &dev->mdev_events);
++
++ for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
++ cancel_work_sync(&devr->ports[port].pkey_change_work);
+ }
+
+ void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
+@@ -4223,9 +4284,6 @@ static const struct mlx5_ib_profile pf_profile = {
+ STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
+ mlx5_ib_dev_res_init,
+ mlx5_ib_dev_res_cleanup),
+- STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
+- mlx5_ib_stage_dev_notifier_init,
+- mlx5_ib_stage_dev_notifier_cleanup),
+ STAGE_CREATE(MLX5_IB_STAGE_ODP,
+ mlx5_ib_odp_init_one,
+ mlx5_ib_odp_cleanup_one),
+@@ -4250,6 +4308,9 @@ static const struct mlx5_ib_profile pf_profile = {
+ STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
+ mlx5_ib_stage_ib_reg_init,
+ mlx5_ib_stage_ib_reg_cleanup),
++ STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
++ mlx5_ib_stage_dev_notifier_init,
++ mlx5_ib_stage_dev_notifier_cleanup),
+ STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
+ mlx5_ib_stage_post_ib_reg_umr_init,
+ NULL),
+@@ -4286,9 +4347,6 @@ const struct mlx5_ib_profile raw_eth_profile = {
+ STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
+ mlx5_ib_dev_res_init,
+ mlx5_ib_dev_res_cleanup),
+- STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
+- mlx5_ib_stage_dev_notifier_init,
+- mlx5_ib_stage_dev_notifier_cleanup),
+ STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
+ mlx5_ib_counters_init,
+ mlx5_ib_counters_cleanup),
+@@ -4310,6 +4368,9 @@ const struct mlx5_ib_profile raw_eth_profile = {
+ STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
+ mlx5_ib_stage_ib_reg_init,
+ mlx5_ib_stage_ib_reg_cleanup),
++ STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
++ mlx5_ib_stage_dev_notifier_init,
++ mlx5_ib_stage_dev_notifier_cleanup),
+ STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
+ mlx5_ib_stage_post_ib_reg_umr_init,
+ NULL),
+diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
+index 43a963e205eb40..94678e5c59dd59 100644
+--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
++++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
+@@ -820,11 +820,13 @@ struct mlx5_ib_port_resources {
+
+ struct mlx5_ib_resources {
+ struct ib_cq *c0;
++ struct mutex cq_lock;
+ u32 xrcdn0;
+ u32 xrcdn1;
+ struct ib_pd *p0;
+ struct ib_srq *s0;
+ struct ib_srq *s1;
++ struct mutex srq_lock;
+ struct mlx5_ib_port_resources ports[2];
+ };
+
+@@ -952,7 +954,6 @@ enum mlx5_ib_stages {
+ MLX5_IB_STAGE_QP,
+ MLX5_IB_STAGE_SRQ,
+ MLX5_IB_STAGE_DEVICE_RESOURCES,
+- MLX5_IB_STAGE_DEVICE_NOTIFIER,
+ MLX5_IB_STAGE_ODP,
+ MLX5_IB_STAGE_COUNTERS,
+ MLX5_IB_STAGE_CONG_DEBUGFS,
+@@ -961,6 +962,7 @@ enum mlx5_ib_stages {
+ MLX5_IB_STAGE_PRE_IB_REG_UMR,
+ MLX5_IB_STAGE_WHITELIST_UID,
+ MLX5_IB_STAGE_IB_REG,
++ MLX5_IB_STAGE_DEVICE_NOTIFIER,
+ MLX5_IB_STAGE_POST_IB_REG_UMR,
+ MLX5_IB_STAGE_DELAY_DROP,
+ MLX5_IB_STAGE_RESTRACK,
+@@ -1270,6 +1272,8 @@ to_mmmap(struct rdma_user_mmap_entry *rdma_entry)
+ struct mlx5_user_mmap_entry, rdma_entry);
+ }
+
++int mlx5_ib_dev_res_cq_init(struct mlx5_ib_dev *dev);
++int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev);
+ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
+ struct mlx5_db *db);
+ void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db);
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index 93d9b15cbbb986..71a856409cee2c 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -3247,6 +3247,10 @@ int mlx5_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
+ enum ib_qp_type type;
+ int err;
+
++ err = mlx5_ib_dev_res_srq_init(dev);
++ if (err)
++ return err;
++
+ err = check_qp_type(dev, attr, &type);
+ if (err)
+ return err;
+diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
+index 84be0c3d569959..bcb6b324af5062 100644
+--- a/drivers/infiniband/hw/mlx5/srq.c
++++ b/drivers/infiniband/hw/mlx5/srq.c
+@@ -216,6 +216,10 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq,
+ return -EINVAL;
+ }
+
++ err = mlx5_ib_dev_res_cq_init(dev);
++ if (err)
++ return err;
++
+ mutex_init(&srq->mutex);
+ spin_lock_init(&srq->lock);
+ srq->msrq.max = roundup_pow_of_two(init_attr->attr.max_wr + 1);
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 28e379c108bce0..3767d7fc0aac82 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -781,6 +781,7 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)
+ * Yield the processor
+ */
+ spin_lock_irqsave(&qp->state_lock, flags);
++ attr->cur_qp_state = qp_state(qp);
+ if (qp->attr.sq_draining) {
+ spin_unlock_irqrestore(&qp->state_lock, flags);
+ cond_resched();
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index 7a36080d2baef5..7ff152ffe15b9f 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -693,10 +693,12 @@ int rxe_requester(struct rxe_qp *qp)
+ if (unlikely(qp_state(qp) == IB_QPS_ERR)) {
+ wqe = __req_next_wqe(qp);
+ spin_unlock_irqrestore(&qp->state_lock, flags);
+- if (wqe)
++ if (wqe) {
++ wqe->status = IB_WC_WR_FLUSH_ERR;
+ goto err;
+- else
++ } else {
+ goto exit;
++ }
+ }
+
+ if (unlikely(qp_state(qp) == IB_QPS_RESET)) {
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index 3a7c647d3affa8..d6381c00bb8ddc 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -815,14 +815,15 @@ static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn,
+ while (1) {
+ offset = pfn_level_offset(pfn, level);
+ pte = &parent[offset];
+- if (!pte || (dma_pte_superpage(pte) || !dma_pte_present(pte))) {
+- pr_info("PTE not present at level %d\n", level);
+- break;
+- }
+
+ pr_info("pte level: %d, pte value: 0x%016llx\n", level, pte->val);
+
+- if (level == 1)
++ if (!dma_pte_present(pte)) {
++ pr_info("page table not present at level %d\n", level - 1);
++ break;
++ }
++
++ if (level == 1 || dma_pte_superpage(pte))
+ break;
+
+ parent = phys_to_virt(dma_pte_addr(pte));
+@@ -845,11 +846,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
+ pr_info("Dump %s table entries for IOVA 0x%llx\n", iommu->name, addr);
+
+ /* root entry dump */
+- rt_entry = &iommu->root_entry[bus];
+- if (!rt_entry) {
+- pr_info("root table entry is not present\n");
++ if (!iommu->root_entry) {
++ pr_info("root table is not present\n");
+ return;
+ }
++ rt_entry = &iommu->root_entry[bus];
+
+ if (sm_supported(iommu))
+ pr_info("scalable mode root entry: hi 0x%016llx, low 0x%016llx\n",
+@@ -860,7 +861,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
+ /* context entry dump */
+ ctx_entry = iommu_context_addr(iommu, bus, devfn, 0);
+ if (!ctx_entry) {
+- pr_info("context table entry is not present\n");
++ pr_info("context table is not present\n");
+ return;
+ }
+
+@@ -869,17 +870,23 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
+
+ /* legacy mode does not require PASID entries */
+ if (!sm_supported(iommu)) {
++ if (!context_present(ctx_entry)) {
++ pr_info("legacy mode page table is not present\n");
++ return;
++ }
+ level = agaw_to_level(ctx_entry->hi & 7);
+ pgtable = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
+ goto pgtable_walk;
+ }
+
+- /* get the pointer to pasid directory entry */
+- dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
+- if (!dir) {
+- pr_info("pasid directory entry is not present\n");
++ if (!context_present(ctx_entry)) {
++ pr_info("pasid directory table is not present\n");
+ return;
+ }
++
++ /* get the pointer to pasid directory entry */
++ dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
++
+ /* For request-without-pasid, get the pasid from context entry */
+ if (intel_iommu_sm && pasid == IOMMU_PASID_INVALID)
+ pasid = IOMMU_NO_PASID;
+@@ -891,7 +898,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
+ /* get the pointer to the pasid table entry */
+ entries = get_pasid_table_from_pde(pde);
+ if (!entries) {
+- pr_info("pasid table entry is not present\n");
++ pr_info("pasid table is not present\n");
+ return;
+ }
+ index = pasid & PASID_PTE_MASK;
+@@ -899,6 +906,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
+ for (i = 0; i < ARRAY_SIZE(pte->val); i++)
+ pr_info("pasid table entry[%d]: 0x%016llx\n", i, pte->val[i]);
+
++ if (!pasid_pte_is_present(pte)) {
++ pr_info("scalable mode page table is not present\n");
++ return;
++ }
++
+ if (pasid_pte_get_pgtt(pte) == PASID_ENTRY_PGTT_FL_ONLY) {
+ level = pte->val[2] & BIT_ULL(2) ? 5 : 4;
+ pgtable = phys_to_virt(pte->val[2] & VTD_PAGE_MASK);
+diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
+index 934dc97f5df9ed..bc758ab70f4940 100644
+--- a/drivers/iommu/io-pgtable-arm.c
++++ b/drivers/iommu/io-pgtable-arm.c
+@@ -180,6 +180,18 @@ static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
+ return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4);
+ }
+
++/*
++ * Convert an index returned by ARM_LPAE_PGD_IDX(), which can point into
++ * a concatenated PGD, into the maximum number of entries that can be
++ * mapped in the same table page.
++ */
++static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
++{
++ int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data);
++
++ return ptes_per_table - (i & (ptes_per_table - 1));
++}
++
+ static bool selftest_running = false;
+
+ static dma_addr_t __arm_lpae_dma_addr(void *pages)
+@@ -357,7 +369,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
+
+ /* If we can install a leaf entry at this level, then do so */
+ if (size == block_size) {
+- max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
++ max_entries = arm_lpae_max_entries(map_idx_start, data);
+ num_entries = min_t(int, pgcount, max_entries);
+ ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep);
+ if (!ret)
+@@ -557,7 +569,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
+
+ if (size == split_sz) {
+ unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
+- max_entries = ptes_per_table - unmap_idx_start;
++ max_entries = arm_lpae_max_entries(unmap_idx_start, data);
+ num_entries = min_t(int, pgcount, max_entries);
+ }
+
+@@ -615,7 +627,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
+
+ /* If the size matches this level, we're in the right place */
+ if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) {
+- max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start;
++ max_entries = arm_lpae_max_entries(unmap_idx_start, data);
+ num_entries = min_t(int, pgcount, max_entries);
+
+ while (i < num_entries) {
+diff --git a/drivers/leds/flash/leds-mt6360.c b/drivers/leds/flash/leds-mt6360.c
+index fdf0812774ceee..7abd535dce3198 100644
+--- a/drivers/leds/flash/leds-mt6360.c
++++ b/drivers/leds/flash/leds-mt6360.c
+@@ -774,7 +774,6 @@ static void mt6360_v4l2_flash_release(struct mt6360_priv *priv)
+ static int mt6360_led_probe(struct platform_device *pdev)
+ {
+ struct mt6360_priv *priv;
+- struct fwnode_handle *child;
+ size_t count;
+ int i = 0, ret;
+
+@@ -801,7 +800,7 @@ static int mt6360_led_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- device_for_each_child_node(&pdev->dev, child) {
++ device_for_each_child_node_scoped(&pdev->dev, child) {
+ struct mt6360_led *led = priv->leds + i;
+ struct led_init_data init_data = { .fwnode = child, };
+ u32 reg, led_color;
+diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
+index 77bb26906ea6e4..84028800aed33b 100644
+--- a/drivers/leds/leds-lp55xx-common.c
++++ b/drivers/leds/leds-lp55xx-common.c
+@@ -580,9 +580,6 @@ static int lp55xx_parse_common_child(struct device_node *np,
+ if (ret)
+ return ret;
+
+- if (*chan_nr < 0 || *chan_nr > cfg->max_channel)
+- return -EINVAL;
+-
+ return 0;
+ }
+
+diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
+index 0ec21dcdbde723..cff7c343ee082a 100644
+--- a/drivers/mailbox/arm_mhuv2.c
++++ b/drivers/mailbox/arm_mhuv2.c
+@@ -500,7 +500,7 @@ static const struct mhuv2_protocol_ops mhuv2_data_transfer_ops = {
+ static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg)
+ {
+ struct mbox_chan *chans = mhu->mbox.chans;
+- int channel = 0, i, offset = 0, windows, protocol, ch_wn;
++ int channel = 0, i, j, offset = 0, windows, protocol, ch_wn;
+ u32 stat;
+
+ for (i = 0; i < MHUV2_CMB_INT_ST_REG_CNT; i++) {
+@@ -510,9 +510,9 @@ static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg)
+
+ ch_wn = i * MHUV2_STAT_BITS + __builtin_ctz(stat);
+
+- for (i = 0; i < mhu->length; i += 2) {
+- protocol = mhu->protocols[i];
+- windows = mhu->protocols[i + 1];
++ for (j = 0; j < mhu->length; j += 2) {
++ protocol = mhu->protocols[j];
++ windows = mhu->protocols[j + 1];
+
+ if (ch_wn >= offset + windows) {
+ if (protocol == DOORBELL)
+diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
+index 4d62b07c14118a..d5f5606585f4d8 100644
+--- a/drivers/mailbox/mtk-cmdq-mailbox.c
++++ b/drivers/mailbox/mtk-cmdq-mailbox.c
+@@ -623,12 +623,6 @@ static int cmdq_probe(struct platform_device *pdev)
+ cmdq->mbox.chans[i].con_priv = (void *)&cmdq->thread[i];
+ }
+
+- err = devm_mbox_controller_register(dev, &cmdq->mbox);
+- if (err < 0) {
+- dev_err(dev, "failed to register mailbox: %d\n", err);
+- return err;
+- }
+-
+ platform_set_drvdata(pdev, cmdq);
+
+ WARN_ON(clk_bulk_prepare(cmdq->pdata->gce_num, cmdq->clocks));
+@@ -642,6 +636,12 @@ static int cmdq_probe(struct platform_device *pdev)
+ return err;
+ }
+
++ err = devm_mbox_controller_register(dev, &cmdq->mbox);
++ if (err < 0) {
++ dev_err(dev, "failed to register mailbox: %d\n", err);
++ return err;
++ }
++
+ return 0;
+ }
+
+diff --git a/drivers/md/bcache/closure.c b/drivers/md/bcache/closure.c
+index d8d9394a6beb10..18f21d4e9aaae8 100644
+--- a/drivers/md/bcache/closure.c
++++ b/drivers/md/bcache/closure.c
+@@ -17,10 +17,16 @@ static inline void closure_put_after_sub(struct closure *cl, int flags)
+ {
+ int r = flags & CLOSURE_REMAINING_MASK;
+
+- BUG_ON(flags & CLOSURE_GUARD_MASK);
+- BUG_ON(!r && (flags & ~CLOSURE_DESTRUCTOR));
++ if (WARN(flags & CLOSURE_GUARD_MASK,
++ "closure has guard bits set: %x (%u)",
++ flags & CLOSURE_GUARD_MASK, (unsigned) __fls(r)))
++ r &= ~CLOSURE_GUARD_MASK;
+
+ if (!r) {
++ WARN(flags & ~CLOSURE_DESTRUCTOR,
++ "closure ref hit 0 with incorrect flags set: %x (%u)",
++ flags & ~CLOSURE_DESTRUCTOR, (unsigned) __fls(flags));
++
+ if (cl->fn && !(flags & CLOSURE_DESTRUCTOR)) {
+ atomic_set(&cl->remaining,
+ CLOSURE_REMAINING_INITIALIZER);
+diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
+index f1345781c861a8..30ddfb21f65818 100644
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -2444,7 +2444,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
+ int r;
+ unsigned int num_locks;
+ struct dm_bufio_client *c;
+- char slab_name[27];
++ char slab_name[64];
++ static atomic_t seqno = ATOMIC_INIT(0);
+
+ if (!block_size || block_size & ((1 << SECTOR_SHIFT) - 1)) {
+ DMERR("%s: block size not specified or is not multiple of 512b", __func__);
+@@ -2495,7 +2496,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
+ (block_size < PAGE_SIZE || !is_power_of_2(block_size))) {
+ unsigned int align = min(1U << __ffs(block_size), (unsigned int)PAGE_SIZE);
+
+- snprintf(slab_name, sizeof(slab_name), "dm_bufio_cache-%u", block_size);
++ snprintf(slab_name, sizeof(slab_name), "dm_bufio_cache-%u-%u",
++ block_size, atomic_inc_return(&seqno));
+ c->slab_cache = kmem_cache_create(slab_name, block_size, align,
+ SLAB_RECLAIM_ACCOUNT, NULL);
+ if (!c->slab_cache) {
+@@ -2504,9 +2506,11 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
+ }
+ }
+ if (aux_size)
+- snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer-%u", aux_size);
++ snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer-%u-%u",
++ aux_size, atomic_inc_return(&seqno));
+ else
+- snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer");
++ snprintf(slab_name, sizeof(slab_name), "dm_bufio_buffer-%u",
++ atomic_inc_return(&seqno));
+ c->slab_buffer = kmem_cache_create(slab_name, sizeof(struct dm_buffer) + aux_size,
+ 0, SLAB_RECLAIM_ACCOUNT, NULL);
+ if (!c->slab_buffer) {
+diff --git a/drivers/md/dm-cache-background-tracker.c b/drivers/md/dm-cache-background-tracker.c
+index 9c5308298cf124..f3051bd7d2df07 100644
+--- a/drivers/md/dm-cache-background-tracker.c
++++ b/drivers/md/dm-cache-background-tracker.c
+@@ -11,12 +11,6 @@
+
+ #define DM_MSG_PREFIX "dm-background-tracker"
+
+-struct bt_work {
+- struct list_head list;
+- struct rb_node node;
+- struct policy_work work;
+-};
+-
+ struct background_tracker {
+ unsigned int max_work;
+ atomic_t pending_promotes;
+@@ -26,10 +20,10 @@ struct background_tracker {
+ struct list_head issued;
+ struct list_head queued;
+ struct rb_root pending;
+-
+- struct kmem_cache *work_cache;
+ };
+
++struct kmem_cache *btracker_work_cache = NULL;
++
+ struct background_tracker *btracker_create(unsigned int max_work)
+ {
+ struct background_tracker *b = kmalloc(sizeof(*b), GFP_KERNEL);
+@@ -48,12 +42,6 @@ struct background_tracker *btracker_create(unsigned int max_work)
+ INIT_LIST_HEAD(&b->queued);
+
+ b->pending = RB_ROOT;
+- b->work_cache = KMEM_CACHE(bt_work, 0);
+- if (!b->work_cache) {
+- DMERR("couldn't create mempool for background work items");
+- kfree(b);
+- b = NULL;
+- }
+
+ return b;
+ }
+@@ -66,10 +54,9 @@ void btracker_destroy(struct background_tracker *b)
+ BUG_ON(!list_empty(&b->issued));
+ list_for_each_entry_safe (w, tmp, &b->queued, list) {
+ list_del(&w->list);
+- kmem_cache_free(b->work_cache, w);
++ kmem_cache_free(btracker_work_cache, w);
+ }
+
+- kmem_cache_destroy(b->work_cache);
+ kfree(b);
+ }
+ EXPORT_SYMBOL_GPL(btracker_destroy);
+@@ -180,7 +167,7 @@ static struct bt_work *alloc_work(struct background_tracker *b)
+ if (max_work_reached(b))
+ return NULL;
+
+- return kmem_cache_alloc(b->work_cache, GFP_NOWAIT);
++ return kmem_cache_alloc(btracker_work_cache, GFP_NOWAIT);
+ }
+
+ int btracker_queue(struct background_tracker *b,
+@@ -203,7 +190,7 @@ int btracker_queue(struct background_tracker *b,
+ * There was a race, we'll just ignore this second
+ * bit of work for the same oblock.
+ */
+- kmem_cache_free(b->work_cache, w);
++ kmem_cache_free(btracker_work_cache, w);
+ return -EINVAL;
+ }
+
+@@ -244,7 +231,7 @@ void btracker_complete(struct background_tracker *b,
+ update_stats(b, &w->work, -1);
+ rb_erase(&w->node, &b->pending);
+ list_del(&w->list);
+- kmem_cache_free(b->work_cache, w);
++ kmem_cache_free(btracker_work_cache, w);
+ }
+ EXPORT_SYMBOL_GPL(btracker_complete);
+
+diff --git a/drivers/md/dm-cache-background-tracker.h b/drivers/md/dm-cache-background-tracker.h
+index 5b8f5c667b81b4..09c8fc59f7bb7b 100644
+--- a/drivers/md/dm-cache-background-tracker.h
++++ b/drivers/md/dm-cache-background-tracker.h
+@@ -26,6 +26,14 @@
+ * protected with a spinlock.
+ */
+
++struct bt_work {
++ struct list_head list;
++ struct rb_node node;
++ struct policy_work work;
++};
++
++extern struct kmem_cache *btracker_work_cache;
++
+ struct background_work;
+ struct background_tracker;
+
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
+index fb809b46d6aa76..c5851c9f7ec041 100644
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -10,6 +10,7 @@
+ #include "dm-bio-record.h"
+ #include "dm-cache-metadata.h"
+ #include "dm-io-tracker.h"
++#include "dm-cache-background-tracker.h"
+
+ #include <linux/dm-io.h>
+ #include <linux/dm-kcopyd.h>
+@@ -2267,7 +2268,7 @@ static int parse_cache_args(struct cache_args *ca, int argc, char **argv,
+
+ /*----------------------------------------------------------------*/
+
+-static struct kmem_cache *migration_cache;
++static struct kmem_cache *migration_cache = NULL;
+
+ #define NOT_CORE_OPTION 1
+
+@@ -3455,22 +3456,36 @@ static int __init dm_cache_init(void)
+ int r;
+
+ migration_cache = KMEM_CACHE(dm_cache_migration, 0);
+- if (!migration_cache)
+- return -ENOMEM;
++ if (!migration_cache) {
++ r = -ENOMEM;
++ goto err;
++ }
++
++ btracker_work_cache = kmem_cache_create("dm_cache_bt_work",
++ sizeof(struct bt_work), __alignof__(struct bt_work), 0, NULL);
++ if (!btracker_work_cache) {
++ r = -ENOMEM;
++ goto err;
++ }
+
+ r = dm_register_target(&cache_target);
+ if (r) {
+- kmem_cache_destroy(migration_cache);
+- return r;
++ goto err;
+ }
+
+ return 0;
++
++err:
++ kmem_cache_destroy(migration_cache);
++ kmem_cache_destroy(btracker_work_cache);
++ return r;
+ }
+
+ static void __exit dm_cache_exit(void)
+ {
+ dm_unregister_target(&cache_target);
+ kmem_cache_destroy(migration_cache);
++ kmem_cache_destroy(btracker_work_cache);
+ }
+
+ module_init(dm_cache_init);
+diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
+index 07c7f9795b107b..032cefe3e351aa 100644
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -2486,6 +2486,7 @@ static void pool_work_wait(struct pool_work *pw, struct pool *pool,
+ init_completion(&pw->complete);
+ queue_work(pool->wq, &pw->worker);
+ wait_for_completion(&pw->complete);
++ destroy_work_on_stack(&pw->worker);
+ }
+
+ /*----------------------------------------------------------------*/
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index be65472d8f8b35..ba63076cd8f2b2 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -1089,6 +1089,7 @@ void md_bitmap_unplug_async(struct bitmap *bitmap)
+
+ queue_work(md_bitmap_wq, &unplug_work.work);
+ wait_for_completion(&done);
++ destroy_work_on_stack(&unplug_work.work);
+ }
+ EXPORT_SYMBOL(md_bitmap_unplug_async);
+
+diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c
+index 591d1a43d03572..101736b80df826 100644
+--- a/drivers/md/persistent-data/dm-space-map-common.c
++++ b/drivers/md/persistent-data/dm-space-map-common.c
+@@ -51,7 +51,7 @@ static int index_check(struct dm_block_validator *v,
+ block_size - sizeof(__le32),
+ INDEX_CSUM_XOR));
+ if (csum_disk != mi_le->csum) {
+- DMERR_LIMIT("i%s failed: csum %u != wanted %u", __func__,
++ DMERR_LIMIT("%s failed: csum %u != wanted %u", __func__,
+ le32_to_cpu(csum_disk), le32_to_cpu(mi_le->csum));
+ return -EILSEQ;
+ }
+diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c
+index a5ebce57f35e6e..d49facd92cc00c 100644
+--- a/drivers/media/dvb-frontends/ts2020.c
++++ b/drivers/media/dvb-frontends/ts2020.c
+@@ -553,13 +553,19 @@ static void ts2020_regmap_unlock(void *__dev)
+ static int ts2020_probe(struct i2c_client *client)
+ {
+ struct ts2020_config *pdata = client->dev.platform_data;
+- struct dvb_frontend *fe = pdata->fe;
++ struct dvb_frontend *fe;
+ struct ts2020_priv *dev;
+ int ret;
+ u8 u8tmp;
+ unsigned int utmp;
+ char *chip_str;
+
++ if (!pdata) {
++ dev_err(&client->dev, "platform data is mandatory\n");
++ return -EINVAL;
++ }
++
++ fe = pdata->fe;
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
+index d1609bd8f0485a..3bd31b5870233e 100644
+--- a/drivers/media/i2c/adv7604.c
++++ b/drivers/media/i2c/adv7604.c
+@@ -1405,12 +1405,13 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
+ if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
+ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+- false, timings))
++ false, adv76xx_get_dv_timings_cap(sd, -1), timings))
+ return 0;
+ if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
+ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+- false, state->aspect_ratio, timings))
++ false, state->aspect_ratio,
++ adv76xx_get_dv_timings_cap(sd, -1), timings))
+ return 0;
+
+ v4l2_dbg(2, debug, sd,
+diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
+index c1664a3620c8ed..cb90178ce4b176 100644
+--- a/drivers/media/i2c/adv7842.c
++++ b/drivers/media/i2c/adv7842.c
+@@ -1431,14 +1431,15 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
+ }
+
+ if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
+- (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+- (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+- false, timings))
++ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
++ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
++ false, adv7842_get_dv_timings_cap(sd), timings))
+ return 0;
+ if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
+- (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+- (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+- false, state->aspect_ratio, timings))
++ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
++ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
++ false, state->aspect_ratio,
++ adv7842_get_dv_timings_cap(sd), timings))
+ return 0;
+
+ v4l2_dbg(2, debug, sd,
+diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c
+index 8ba5750f5a2319..7f30e8923633ef 100644
+--- a/drivers/media/i2c/ds90ub960.c
++++ b/drivers/media/i2c/ds90ub960.c
+@@ -1286,7 +1286,7 @@ static int ub960_rxport_get_strobe_pos(struct ub960_data *priv,
+
+ clk_delay += v & UB960_IR_RX_ANA_STROBE_SET_CLK_DELAY_MASK;
+
+- ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v);
++ ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
+index daabbece8c7e90..682a1aa7febd97 100644
+--- a/drivers/media/i2c/dw9768.c
++++ b/drivers/media/i2c/dw9768.c
+@@ -476,10 +476,9 @@ static int dw9768_probe(struct i2c_client *client)
+ * to be powered on in an ACPI system. Similarly for power off in
+ * remove.
+ */
+- pm_runtime_enable(dev);
+ full_power = (is_acpi_node(dev_fwnode(dev)) &&
+ acpi_dev_state_d0(dev)) ||
+- (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev));
++ (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM));
+ if (full_power) {
+ ret = dw9768_runtime_resume(dev);
+ if (ret < 0) {
+@@ -489,6 +488,7 @@ static int dw9768_probe(struct i2c_client *client)
+ pm_runtime_set_active(dev);
+ }
+
++ pm_runtime_enable(dev);
+ ret = v4l2_async_register_subdev(&dw9768->sd);
+ if (ret < 0) {
+ dev_err(dev, "failed to register V4L2 subdev: %d", ret);
+@@ -500,12 +500,12 @@ static int dw9768_probe(struct i2c_client *client)
+ return 0;
+
+ err_power_off:
++ pm_runtime_disable(dev);
+ if (full_power) {
+ dw9768_runtime_suspend(dev);
+ pm_runtime_set_suspended(dev);
+ }
+ err_clean_entity:
+- pm_runtime_disable(dev);
+ media_entity_cleanup(&dw9768->sd.entity);
+ err_free_handler:
+ v4l2_ctrl_handler_free(&dw9768->ctrls);
+@@ -522,12 +522,12 @@ static void dw9768_remove(struct i2c_client *client)
+ v4l2_async_unregister_subdev(&dw9768->sd);
+ v4l2_ctrl_handler_free(&dw9768->ctrls);
+ media_entity_cleanup(&dw9768->sd.entity);
++ pm_runtime_disable(dev);
+ if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) ||
+- (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) {
++ (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM))) {
+ dw9768_runtime_suspend(dev);
+ pm_runtime_set_suspended(dev);
+ }
+- pm_runtime_disable(dev);
+ }
+
+ static const struct of_device_id dw9768_of_table[] = {
+diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
+index 558152575d1022..c81dd41834043f 100644
+--- a/drivers/media/i2c/tc358743.c
++++ b/drivers/media/i2c/tc358743.c
+@@ -2159,8 +2159,10 @@ static int tc358743_probe(struct i2c_client *client)
+
+ err_work_queues:
+ cec_unregister_adapter(state->cec_adap);
+- if (!state->i2c_client->irq)
++ if (!state->i2c_client->irq) {
++ del_timer(&state->timer);
+ flush_work(&state->work_i2c_poll);
++ }
+ cancel_delayed_work(&state->delayed_work_enable_hotplug);
+ mutex_destroy(&state->confctl_mutex);
+ err_hdl:
+diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c
+index da61f9beb6b4f5..7dffea2ad88a15 100644
+--- a/drivers/media/platform/allegro-dvt/allegro-core.c
++++ b/drivers/media/platform/allegro-dvt/allegro-core.c
+@@ -1509,8 +1509,10 @@ static int allocate_buffers_internal(struct allegro_channel *channel,
+ INIT_LIST_HEAD(&buffer->head);
+
+ err = allegro_alloc_buffer(dev, buffer, size);
+- if (err)
++ if (err) {
++ kfree(buffer);
+ goto err;
++ }
+ list_add(&buffer->head, list);
+ }
+
+diff --git a/drivers/media/platform/amphion/vpu_drv.c b/drivers/media/platform/amphion/vpu_drv.c
+index 2bf70aafd2baab..51d5234869f57d 100644
+--- a/drivers/media/platform/amphion/vpu_drv.c
++++ b/drivers/media/platform/amphion/vpu_drv.c
+@@ -151,8 +151,8 @@ static int vpu_probe(struct platform_device *pdev)
+ media_device_cleanup(&vpu->mdev);
+ v4l2_device_unregister(&vpu->v4l2_dev);
+ err_vpu_deinit:
+- pm_runtime_set_suspended(dev);
+ pm_runtime_disable(dev);
++ pm_runtime_set_suspended(dev);
+
+ return ret;
+ }
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index d7e0de49b3dcef..61d27b63b99d47 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -825,6 +825,7 @@ int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func)
+ vfd->fops = vdec_get_fops();
+ vfd->ioctl_ops = vdec_get_ioctl_ops();
+ }
++ video_set_drvdata(vfd, vpu);
+
+ ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+@@ -832,7 +833,6 @@ int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func)
+ v4l2_m2m_release(func->m2m_dev);
+ return ret;
+ }
+- video_set_drvdata(vfd, vpu);
+ func->vfd = vfd;
+
+ ret = v4l2_m2m_register_media_controller(func->m2m_dev, func->vfd, func->function);
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+index c3456c700c07e2..4c7b46f5a7ddd5 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+@@ -1294,6 +1294,11 @@ static int mtk_jpeg_single_core_init(struct platform_device *pdev,
+ return 0;
+ }
+
++static void mtk_jpeg_destroy_workqueue(void *data)
++{
++ destroy_workqueue(data);
++}
++
+ static int mtk_jpeg_probe(struct platform_device *pdev)
+ {
+ struct mtk_jpeg_dev *jpeg;
+@@ -1338,6 +1343,11 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
+ | WQ_FREEZABLE);
+ if (!jpeg->workqueue)
+ return -EINVAL;
++ ret = devm_add_action_or_reset(&pdev->dev,
++ mtk_jpeg_destroy_workqueue,
++ jpeg->workqueue);
++ if (ret)
++ return ret;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+index 4a6ee211e18f97..2c5d74939d0a92 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+@@ -578,11 +578,6 @@ static int mtk_jpegdec_hw_init_irq(struct mtk_jpegdec_comp_dev *dev)
+ return 0;
+ }
+
+-static void mtk_jpegdec_destroy_workqueue(void *data)
+-{
+- destroy_workqueue(data);
+-}
+-
+ static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
+ {
+ struct mtk_jpegdec_clk *jpegdec_clk;
+@@ -606,12 +601,6 @@ static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
+ dev->plat_dev = pdev;
+ dev->dev = &pdev->dev;
+
+- ret = devm_add_action_or_reset(&pdev->dev,
+- mtk_jpegdec_destroy_workqueue,
+- master_dev->workqueue);
+- if (ret)
+- return ret;
+-
+ spin_lock_init(&dev->hw_lock);
+ dev->hw_state = MTK_JPEG_HW_IDLE;
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 2007152cd7a40d..e8dcd44f6e4692 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -2674,6 +2674,8 @@ static void mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev *jpeg)
+ int i;
+
+ for (i = 0; i < jpeg->num_domains; i++) {
++ if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i]))
++ pm_runtime_force_suspend(jpeg->pd_dev[i]);
+ if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i]))
+ device_link_del(jpeg->pd_link[i]);
+ if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i]))
+@@ -2837,6 +2839,7 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+ jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
+ jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
+ V4L2_CAP_VIDEO_M2M_MPLANE;
++ video_set_drvdata(jpeg->dec_vdev, jpeg);
+ if (mode == MXC_JPEG_ENCODE) {
+ v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD);
+ v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD);
+@@ -2849,7 +2852,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+ dev_err(dev, "failed to register video device\n");
+ goto err_vdev_register;
+ }
+- video_set_drvdata(jpeg->dec_vdev, jpeg);
+ if (mode == MXC_JPEG_ENCODE)
+ v4l2_info(&jpeg->v4l2_dev,
+ "encoder device registered as /dev/video%d (%d,%d)\n",
+diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
+index 0fc9414f8f1849..b570eb8c37568f 100644
+--- a/drivers/media/platform/qcom/venus/core.c
++++ b/drivers/media/platform/qcom/venus/core.c
+@@ -406,8 +406,8 @@ static int venus_probe(struct platform_device *pdev)
+ of_platform_depopulate(dev);
+ err_runtime_disable:
+ pm_runtime_put_noidle(dev);
+- pm_runtime_set_suspended(dev);
+ pm_runtime_disable(dev);
++ pm_runtime_set_suspended(dev);
+ hfi_destroy(core);
+ err_core_deinit:
+ hfi_core_deinit(core, false);
+diff --git a/drivers/media/platform/samsung/exynos4-is/media-dev.h b/drivers/media/platform/samsung/exynos4-is/media-dev.h
+index 786264cf79dc14..a50e58ab7ef773 100644
+--- a/drivers/media/platform/samsung/exynos4-is/media-dev.h
++++ b/drivers/media/platform/samsung/exynos4-is/media-dev.h
+@@ -178,8 +178,9 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
+ #ifdef CONFIG_OF
+ static inline bool fimc_md_is_isp_available(struct device_node *node)
+ {
+- node = of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME);
+- return node ? of_device_is_available(node) : false;
++ struct device_node *child __free(device_node) =
++ of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME);
++ return child ? of_device_is_available(child) : false;
+ }
+ #else
+ #define fimc_md_is_isp_available(node) (false)
+diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+index cc4483857489c5..ff78b31728290d 100644
+--- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
++++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+@@ -161,8 +161,7 @@ static int rockchip_vpu981_av1_dec_frame_ref(struct hantro_ctx *ctx,
+ av1_dec->frame_refs[i].timestamp = timestamp;
+ av1_dec->frame_refs[i].frame_type = frame->frame_type;
+ av1_dec->frame_refs[i].order_hint = frame->order_hint;
+- if (!av1_dec->frame_refs[i].vb2_ref)
+- av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx);
++ av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx);
+
+ for (j = 0; j < V4L2_AV1_TOTAL_REFS_PER_FRAME; j++)
+ av1_dec->frame_refs[i].order_hints[j] = frame->order_hints[j];
+diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
+index 3da8e5102becc2..1225dab9fc7d3e 100644
+--- a/drivers/media/radio/wl128x/fmdrv_common.c
++++ b/drivers/media/radio/wl128x/fmdrv_common.c
+@@ -466,11 +466,12 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
+ jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
+ return -ETIMEDOUT;
+ }
++ spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
+ if (!fmdev->resp_skb) {
++ spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
+ fmerr("Response SKB is missing\n");
+ return -EFAULT;
+ }
+- spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
+ skb = fmdev->resp_skb;
+ fmdev->resp_skb = NULL;
+ spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
+diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+index 99325bfed64310..9443dbb04699a3 100644
+--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+@@ -1466,12 +1466,19 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
+ h_freq = (u32)bt->pixelclock / total_h_pixel;
+
+ if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) {
++ struct v4l2_dv_timings cvt = {};
++
+ if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, bt->width,
+- bt->polarities, bt->interlaced, timings))
++ bt->polarities, bt->interlaced,
++ &vivid_dv_timings_cap, &cvt) &&
++ cvt.bt.width == bt->width && cvt.bt.height == bt->height) {
++ *timings = cvt;
+ return true;
++ }
+ }
+
+ if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) {
++ struct v4l2_dv_timings gtf = {};
+ struct v4l2_fract aspect_ratio;
+
+ find_aspect_ratio(bt->width, bt->height,
+@@ -1479,8 +1486,12 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
+ &aspect_ratio.denominator);
+ if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync,
+ bt->polarities, bt->interlaced,
+- aspect_ratio, timings))
++ aspect_ratio, &vivid_dv_timings_cap,
++ &gtf) &&
++ gtf.bt.width == bt->width && gtf.bt.height == bt->height) {
++ *timings = gtf;
+ return true;
++ }
+ }
+ return false;
+ }
+diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c
+index 8b6a57f170d0dd..bdff64a29a33a2 100644
+--- a/drivers/media/usb/gspca/ov534.c
++++ b/drivers/media/usb/gspca/ov534.c
+@@ -847,7 +847,7 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
+ r = rate_1;
+ i = ARRAY_SIZE(rate_1);
+ }
+- while (--i > 0) {
++ while (--i >= 0) {
+ if (sd->frame_rate >= r->fps)
+ break;
+ r++;
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index 37d75bc97fd8dc..1385cbf462d172 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -775,14 +775,27 @@ static const u8 uvc_media_transport_input_guid[16] =
+ UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
+ static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
+
+-static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
+- unsigned int num_pads, unsigned int extra_size)
++static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type,
++ u16 id, unsigned int num_pads,
++ unsigned int extra_size)
+ {
+ struct uvc_entity *entity;
+ unsigned int num_inputs;
+ unsigned int size;
+ unsigned int i;
+
++ /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */
++ if (id == 0) {
++ dev_err(&dev->udev->dev, "Found Unit with invalid ID 0.\n");
++ return ERR_PTR(-EINVAL);
++ }
++
++ /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */
++ if (uvc_entity_by_id(dev, id)) {
++ dev_err(&dev->udev->dev, "Found multiple Units with ID %u\n", id);
++ return ERR_PTR(-EINVAL);
++ }
++
+ extra_size = roundup(extra_size, sizeof(*entity->pads));
+ if (num_pads)
+ num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1;
+@@ -792,7 +805,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
+ + num_inputs;
+ entity = kzalloc(size, GFP_KERNEL);
+ if (entity == NULL)
+- return NULL;
++ return ERR_PTR(-ENOMEM);
+
+ entity->id = id;
+ entity->type = type;
+@@ -904,10 +917,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
+ break;
+ }
+
+- unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
+- p + 1, 2*n);
+- if (unit == NULL)
+- return -ENOMEM;
++ unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT,
++ buffer[3], p + 1, 2 * n);
++ if (IS_ERR(unit))
++ return PTR_ERR(unit);
+
+ memcpy(unit->guid, &buffer[4], 16);
+ unit->extension.bNumControls = buffer[20];
+@@ -1016,10 +1029,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
+- 1, n + p);
+- if (term == NULL)
+- return -ENOMEM;
++ term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT,
++ buffer[3], 1, n + p);
++ if (IS_ERR(term))
++ return PTR_ERR(term);
+
+ if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
+ term->camera.bControlSize = n;
+@@ -1075,10 +1088,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ return 0;
+ }
+
+- term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
+- 1, 0);
+- if (term == NULL)
+- return -ENOMEM;
++ term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT,
++ buffer[3], 1, 0);
++ if (IS_ERR(term))
++ return PTR_ERR(term);
+
+ memcpy(term->baSourceID, &buffer[7], 1);
+
+@@ -1097,9 +1110,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
+- if (unit == NULL)
+- return -ENOMEM;
++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],
++ p + 1, 0);
++ if (IS_ERR(unit))
++ return PTR_ERR(unit);
+
+ memcpy(unit->baSourceID, &buffer[5], p);
+
+@@ -1119,9 +1133,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
+- if (unit == NULL)
+- return -ENOMEM;
++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n);
++ if (IS_ERR(unit))
++ return PTR_ERR(unit);
+
+ memcpy(unit->baSourceID, &buffer[4], 1);
+ unit->processing.wMaxMultiplier =
+@@ -1148,9 +1162,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
+- if (unit == NULL)
+- return -ENOMEM;
++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],
++ p + 1, n);
++ if (IS_ERR(unit))
++ return PTR_ERR(unit);
+
+ memcpy(unit->guid, &buffer[4], 16);
+ unit->extension.bNumControls = buffer[20];
+@@ -1290,9 +1305,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)
+ return dev_err_probe(&dev->udev->dev, irq,
+ "No IRQ for privacy GPIO\n");
+
+- unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
+- if (!unit)
+- return -ENOMEM;
++ unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT,
++ UVC_EXT_GPIO_UNIT_ID, 0, 1);
++ if (IS_ERR(unit))
++ return PTR_ERR(unit);
+
+ unit->gpio.gpio_privacy = gpio_privacy;
+ unit->gpio.irq = irq;
+@@ -1919,11 +1935,41 @@ static void uvc_unregister_video(struct uvc_device *dev)
+ struct uvc_streaming *stream;
+
+ list_for_each_entry(stream, &dev->streams, list) {
++ /* Nothing to do here, continue. */
+ if (!video_is_registered(&stream->vdev))
+ continue;
+
++ /*
++ * For stream->vdev we follow the same logic as:
++ * vb2_video_unregister_device().
++ */
++
++ /* 1. Take a reference to vdev */
++ get_device(&stream->vdev.dev);
++
++ /* 2. Ensure that no new ioctls can be called. */
+ video_unregister_device(&stream->vdev);
+- video_unregister_device(&stream->meta.vdev);
++
++ /* 3. Wait for old ioctls to finish. */
++ mutex_lock(&stream->mutex);
++
++ /* 4. Stop streaming. */
++ uvc_queue_release(&stream->queue);
++
++ mutex_unlock(&stream->mutex);
++
++ put_device(&stream->vdev.dev);
++
++ /*
++ * For stream->meta.vdev we can directly call:
++ * vb2_video_unregister_device().
++ */
++ vb2_video_unregister_device(&stream->meta.vdev);
++
++ /*
++ * Now both vdevs are not streaming and all the ioctls will
++ * return -ENODEV.
++ */
+
+ uvc_debugfs_cleanup_stream(stream);
+ }
+diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
+index 942d0005c55e82..2cf5dcee0ce800 100644
+--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
++++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
+@@ -481,25 +481,28 @@ EXPORT_SYMBOL_GPL(v4l2_calc_timeperframe);
+ * @polarities - the horizontal and vertical polarities (same as struct
+ * v4l2_bt_timings polarities).
+ * @interlaced - if this flag is true, it indicates interlaced format
+- * @fmt - the resulting timings.
++ * @cap - the v4l2_dv_timings_cap capabilities.
++ * @timings - the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid CVT format. If so, then it will return true, and fmt will be filled
+ * in with the found CVT timings.
+ */
+-bool v4l2_detect_cvt(unsigned frame_height,
+- unsigned hfreq,
+- unsigned vsync,
+- unsigned active_width,
++bool v4l2_detect_cvt(unsigned int frame_height,
++ unsigned int hfreq,
++ unsigned int vsync,
++ unsigned int active_width,
+ u32 polarities,
+ bool interlaced,
+- struct v4l2_dv_timings *fmt)
++ const struct v4l2_dv_timings_cap *cap,
++ struct v4l2_dv_timings *timings)
+ {
+- int v_fp, v_bp, h_fp, h_bp, hsync;
+- int frame_width, image_height, image_width;
++ struct v4l2_dv_timings t = {};
++ int v_fp, v_bp, h_fp, h_bp, hsync;
++ int frame_width, image_height, image_width;
+ bool reduced_blanking;
+ bool rb_v2 = false;
+- unsigned pix_clk;
++ unsigned int pix_clk;
+
+ if (vsync < 4 || vsync > 8)
+ return false;
+@@ -625,36 +628,39 @@ bool v4l2_detect_cvt(unsigned frame_height,
+ h_fp = h_blank - hsync - h_bp;
+ }
+
+- fmt->type = V4L2_DV_BT_656_1120;
+- fmt->bt.polarities = polarities;
+- fmt->bt.width = image_width;
+- fmt->bt.height = image_height;
+- fmt->bt.hfrontporch = h_fp;
+- fmt->bt.vfrontporch = v_fp;
+- fmt->bt.hsync = hsync;
+- fmt->bt.vsync = vsync;
+- fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
++ t.type = V4L2_DV_BT_656_1120;
++ t.bt.polarities = polarities;
++ t.bt.width = image_width;
++ t.bt.height = image_height;
++ t.bt.hfrontporch = h_fp;
++ t.bt.vfrontporch = v_fp;
++ t.bt.hsync = hsync;
++ t.bt.vsync = vsync;
++ t.bt.hbackporch = frame_width - image_width - h_fp - hsync;
+
+ if (!interlaced) {
+- fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+- fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
++ t.bt.vbackporch = frame_height - image_height - v_fp - vsync;
++ t.bt.interlaced = V4L2_DV_PROGRESSIVE;
+ } else {
+- fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
++ t.bt.vbackporch = (frame_height - image_height - 2 * v_fp -
+ 2 * vsync) / 2;
+- fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
+- 2 * vsync - fmt->bt.vbackporch;
+- fmt->bt.il_vfrontporch = v_fp;
+- fmt->bt.il_vsync = vsync;
+- fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
+- fmt->bt.interlaced = V4L2_DV_INTERLACED;
++ t.bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
++ 2 * vsync - t.bt.vbackporch;
++ t.bt.il_vfrontporch = v_fp;
++ t.bt.il_vsync = vsync;
++ t.bt.flags |= V4L2_DV_FL_HALF_LINE;
++ t.bt.interlaced = V4L2_DV_INTERLACED;
+ }
+
+- fmt->bt.pixelclock = pix_clk;
+- fmt->bt.standards = V4L2_DV_BT_STD_CVT;
++ t.bt.pixelclock = pix_clk;
++ t.bt.standards = V4L2_DV_BT_STD_CVT;
+
+ if (reduced_blanking)
+- fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
++ t.bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+
++ if (!v4l2_valid_dv_timings(&t, cap, NULL, NULL))
++ return false;
++ *timings = t;
+ return true;
+ }
+ EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
+@@ -699,22 +705,25 @@ EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
+ * image height, so it has to be passed explicitly. Usually
+ * the native screen aspect ratio is used for this. If it
+ * is not filled in correctly, then 16:9 will be assumed.
+- * @fmt - the resulting timings.
++ * @cap - the v4l2_dv_timings_cap capabilities.
++ * @timings - the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid GTF format. If so, then it will return true, and fmt will be filled
+ * in with the found GTF timings.
+ */
+-bool v4l2_detect_gtf(unsigned frame_height,
+- unsigned hfreq,
+- unsigned vsync,
+- u32 polarities,
+- bool interlaced,
+- struct v4l2_fract aspect,
+- struct v4l2_dv_timings *fmt)
++bool v4l2_detect_gtf(unsigned int frame_height,
++ unsigned int hfreq,
++ unsigned int vsync,
++ u32 polarities,
++ bool interlaced,
++ struct v4l2_fract aspect,
++ const struct v4l2_dv_timings_cap *cap,
++ struct v4l2_dv_timings *timings)
+ {
++ struct v4l2_dv_timings t = {};
+ int pix_clk;
+- int v_fp, v_bp, h_fp, hsync;
++ int v_fp, v_bp, h_fp, hsync;
+ int frame_width, image_height, image_width;
+ bool default_gtf;
+ int h_blank;
+@@ -783,36 +792,39 @@ bool v4l2_detect_gtf(unsigned frame_height,
+
+ h_fp = h_blank / 2 - hsync;
+
+- fmt->type = V4L2_DV_BT_656_1120;
+- fmt->bt.polarities = polarities;
+- fmt->bt.width = image_width;
+- fmt->bt.height = image_height;
+- fmt->bt.hfrontporch = h_fp;
+- fmt->bt.vfrontporch = v_fp;
+- fmt->bt.hsync = hsync;
+- fmt->bt.vsync = vsync;
+- fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
++ t.type = V4L2_DV_BT_656_1120;
++ t.bt.polarities = polarities;
++ t.bt.width = image_width;
++ t.bt.height = image_height;
++ t.bt.hfrontporch = h_fp;
++ t.bt.vfrontporch = v_fp;
++ t.bt.hsync = hsync;
++ t.bt.vsync = vsync;
++ t.bt.hbackporch = frame_width - image_width - h_fp - hsync;
+
+ if (!interlaced) {
+- fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+- fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
++ t.bt.vbackporch = frame_height - image_height - v_fp - vsync;
++ t.bt.interlaced = V4L2_DV_PROGRESSIVE;
+ } else {
+- fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
++ t.bt.vbackporch = (frame_height - image_height - 2 * v_fp -
+ 2 * vsync) / 2;
+- fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
+- 2 * vsync - fmt->bt.vbackporch;
+- fmt->bt.il_vfrontporch = v_fp;
+- fmt->bt.il_vsync = vsync;
+- fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
+- fmt->bt.interlaced = V4L2_DV_INTERLACED;
++ t.bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
++ 2 * vsync - t.bt.vbackporch;
++ t.bt.il_vfrontporch = v_fp;
++ t.bt.il_vsync = vsync;
++ t.bt.flags |= V4L2_DV_FL_HALF_LINE;
++ t.bt.interlaced = V4L2_DV_INTERLACED;
+ }
+
+- fmt->bt.pixelclock = pix_clk;
+- fmt->bt.standards = V4L2_DV_BT_STD_GTF;
++ t.bt.pixelclock = pix_clk;
++ t.bt.standards = V4L2_DV_BT_STD_GTF;
+
+ if (!default_gtf)
+- fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
++ t.bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+
++ if (!v4l2_valid_dv_timings(&t, cap, NULL, NULL))
++ return false;
++ *timings = t;
+ return true;
+ }
+ EXPORT_SYMBOL_GPL(v4l2_detect_gtf);
+diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
+index 86f16f3ea47870..d97057f46ca864 100644
+--- a/drivers/message/fusion/mptsas.c
++++ b/drivers/message/fusion/mptsas.c
+@@ -4234,10 +4234,8 @@ mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
+ static void
+ mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
+ {
+- int rc;
+-
+ sdev->no_uld_attach = data ? 1 : 0;
+- rc = scsi_device_reprobe(sdev);
++ WARN_ON(scsi_device_reprobe(sdev));
+ }
+
+ static void
+diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c
+index be5f2b34e18aeb..80fc5c0cac2fb0 100644
+--- a/drivers/mfd/da9052-spi.c
++++ b/drivers/mfd/da9052-spi.c
+@@ -37,7 +37,7 @@ static int da9052_spi_probe(struct spi_device *spi)
+ spi_set_drvdata(spi, da9052);
+
+ config = da9052_regmap_config;
+- config.read_flag_mask = 1;
++ config.write_flag_mask = 1;
+ config.reg_bits = 7;
+ config.pad_bits = 1;
+ config.val_bits = 8;
+diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
+index 8dac0d41f64f3e..3aa7857271dadb 100644
+--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
+@@ -231,44 +231,55 @@ static const struct resource tmu_resources[] = {
+ };
+
+ static struct mfd_cell bxt_wc_dev[] = {
+- {
+- .name = "bxt_wcove_gpadc",
+- .num_resources = ARRAY_SIZE(adc_resources),
+- .resources = adc_resources,
+- },
+ {
+ .name = "bxt_wcove_thermal",
+ .num_resources = ARRAY_SIZE(thermal_resources),
+ .resources = thermal_resources,
+ },
+ {
+- .name = "bxt_wcove_usbc",
+- .num_resources = ARRAY_SIZE(usbc_resources),
+- .resources = usbc_resources,
++ .name = "bxt_wcove_gpio",
++ .num_resources = ARRAY_SIZE(gpio_resources),
++ .resources = gpio_resources,
+ },
+ {
+- .name = "bxt_wcove_ext_charger",
+- .num_resources = ARRAY_SIZE(charger_resources),
+- .resources = charger_resources,
++ .name = "bxt_wcove_region",
++ },
++};
++
++static const struct mfd_cell bxt_wc_tmu_dev[] = {
++ {
++ .name = "bxt_wcove_tmu",
++ .num_resources = ARRAY_SIZE(tmu_resources),
++ .resources = tmu_resources,
+ },
++};
++
++static const struct mfd_cell bxt_wc_bcu_dev[] = {
+ {
+ .name = "bxt_wcove_bcu",
+ .num_resources = ARRAY_SIZE(bcu_resources),
+ .resources = bcu_resources,
+ },
++};
++
++static const struct mfd_cell bxt_wc_adc_dev[] = {
+ {
+- .name = "bxt_wcove_tmu",
+- .num_resources = ARRAY_SIZE(tmu_resources),
+- .resources = tmu_resources,
++ .name = "bxt_wcove_gpadc",
++ .num_resources = ARRAY_SIZE(adc_resources),
++ .resources = adc_resources,
+ },
++};
+
++static struct mfd_cell bxt_wc_chgr_dev[] = {
+ {
+- .name = "bxt_wcove_gpio",
+- .num_resources = ARRAY_SIZE(gpio_resources),
+- .resources = gpio_resources,
++ .name = "bxt_wcove_usbc",
++ .num_resources = ARRAY_SIZE(usbc_resources),
++ .resources = usbc_resources,
+ },
+ {
+- .name = "bxt_wcove_region",
++ .name = "bxt_wcove_ext_charger",
++ .num_resources = ARRAY_SIZE(charger_resources),
++ .resources = charger_resources,
+ },
+ };
+
+@@ -426,6 +437,26 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
+ 0, chip, data);
+ }
+
++static int bxtwc_add_chained_devices(struct intel_soc_pmic *pmic,
++ const struct mfd_cell *cells, int n_devs,
++ struct regmap_irq_chip_data *pdata,
++ int pirq, int irq_flags,
++ const struct regmap_irq_chip *chip,
++ struct regmap_irq_chip_data **data)
++{
++ struct device *dev = pmic->dev;
++ struct irq_domain *domain;
++ int ret;
++
++ ret = bxtwc_add_chained_irq_chip(pmic, pdata, pirq, irq_flags, chip, data);
++ if (ret)
++ return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
++
++ domain = regmap_irq_get_domain(*data);
++
++ return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cells, n_devs, NULL, 0, domain);
++}
++
+ static int bxtwc_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -467,6 +498,15 @@ static int bxtwc_probe(struct platform_device *pdev)
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
+
++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_tmu_dev, ARRAY_SIZE(bxt_wc_tmu_dev),
++ pmic->irq_chip_data,
++ BXTWC_TMU_LVL1_IRQ,
++ IRQF_ONESHOT,
++ &bxtwc_regmap_irq_chip_tmu,
++ &pmic->irq_chip_data_tmu);
++ if (ret)
++ return ret;
++
+ ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+ BXTWC_PWRBTN_LVL1_IRQ,
+ IRQF_ONESHOT,
+@@ -475,40 +515,32 @@ static int bxtwc_probe(struct platform_device *pdev)
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
+
+- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+- BXTWC_TMU_LVL1_IRQ,
+- IRQF_ONESHOT,
+- &bxtwc_regmap_irq_chip_tmu,
+- &pmic->irq_chip_data_tmu);
+- if (ret)
+- return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n");
+-
+- /* Add chained IRQ handler for BCU IRQs */
+- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+- BXTWC_BCU_LVL1_IRQ,
+- IRQF_ONESHOT,
+- &bxtwc_regmap_irq_chip_bcu,
+- &pmic->irq_chip_data_bcu);
++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_bcu_dev, ARRAY_SIZE(bxt_wc_bcu_dev),
++ pmic->irq_chip_data,
++ BXTWC_BCU_LVL1_IRQ,
++ IRQF_ONESHOT,
++ &bxtwc_regmap_irq_chip_bcu,
++ &pmic->irq_chip_data_bcu);
+ if (ret)
+- return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n");
++ return ret;
+
+- /* Add chained IRQ handler for ADC IRQs */
+- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+- BXTWC_ADC_LVL1_IRQ,
+- IRQF_ONESHOT,
+- &bxtwc_regmap_irq_chip_adc,
+- &pmic->irq_chip_data_adc);
++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_adc_dev, ARRAY_SIZE(bxt_wc_adc_dev),
++ pmic->irq_chip_data,
++ BXTWC_ADC_LVL1_IRQ,
++ IRQF_ONESHOT,
++ &bxtwc_regmap_irq_chip_adc,
++ &pmic->irq_chip_data_adc);
+ if (ret)
+- return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
++ return ret;
+
+- /* Add chained IRQ handler for CHGR IRQs */
+- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+- BXTWC_CHGR_LVL1_IRQ,
+- IRQF_ONESHOT,
+- &bxtwc_regmap_irq_chip_chgr,
+- &pmic->irq_chip_data_chgr);
++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev),
++ pmic->irq_chip_data,
++ BXTWC_CHGR_LVL1_IRQ,
++ IRQF_ONESHOT,
++ &bxtwc_regmap_irq_chip_chgr,
++ &pmic->irq_chip_data_chgr);
+ if (ret)
+- return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n");
++ return ret;
+
+ /* Add chained IRQ handler for CRIT IRQs */
+ ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c
+index 7e23ab3d5842c8..84ebc96f58e48d 100644
+--- a/drivers/mfd/rt5033.c
++++ b/drivers/mfd/rt5033.c
+@@ -81,8 +81,8 @@ static int rt5033_i2c_probe(struct i2c_client *i2c)
+ chip_rev = dev_id & RT5033_CHIP_REV_MASK;
+ dev_info(&i2c->dev, "Device found (rev. %d)\n", chip_rev);
+
+- ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
+- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
++ ret = devm_regmap_add_irq_chip(rt5033->dev, rt5033->regmap,
++ rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ 0, &rt5033_irq_chip, &rt5033->irq_data);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c
+index 2b9105295f3012..710364435b6b9e 100644
+--- a/drivers/mfd/tps65010.c
++++ b/drivers/mfd/tps65010.c
+@@ -544,17 +544,13 @@ static int tps65010_probe(struct i2c_client *client)
+ */
+ if (client->irq > 0) {
+ status = request_irq(client->irq, tps65010_irq,
+- IRQF_TRIGGER_FALLING, DRIVER_NAME, tps);
++ IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,
++ DRIVER_NAME, tps);
+ if (status < 0) {
+ dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
+ client->irq, status);
+ return status;
+ }
+- /* annoying race here, ideally we'd have an option
+- * to claim the irq now and enable it later.
+- * FIXME genirq IRQF_NOAUTOEN now solves that ...
+- */
+- disable_irq(client->irq);
+ set_bit(FLAG_IRQ_ENABLE, &tps->flags);
+ } else
+ dev_warn(&client->dev, "IRQ not configured!\n");
+diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c
+index 92b92be91d6021..095344a312d2ad 100644
+--- a/drivers/misc/apds990x.c
++++ b/drivers/misc/apds990x.c
+@@ -1147,7 +1147,7 @@ static int apds990x_probe(struct i2c_client *client)
+ err = chip->pdata->setup_resources();
+ if (err) {
+ err = -EINVAL;
+- goto fail3;
++ goto fail4;
+ }
+ }
+
+@@ -1155,7 +1155,7 @@ static int apds990x_probe(struct i2c_client *client)
+ apds990x_attribute_group);
+ if (err < 0) {
+ dev_err(&chip->client->dev, "Sysfs registration failed\n");
+- goto fail4;
++ goto fail5;
+ }
+
+ err = request_threaded_irq(client->irq, NULL,
+@@ -1166,15 +1166,17 @@ static int apds990x_probe(struct i2c_client *client)
+ if (err) {
+ dev_err(&client->dev, "could not get IRQ %d\n",
+ client->irq);
+- goto fail5;
++ goto fail6;
+ }
+ return err;
+-fail5:
++fail6:
+ sysfs_remove_group(&chip->client->dev.kobj,
+ &apds990x_attribute_group[0]);
+-fail4:
++fail5:
+ if (chip->pdata && chip->pdata->release_resources)
+ chip->pdata->release_resources();
++fail4:
++ pm_runtime_disable(&client->dev);
+ fail3:
+ regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
+ fail2:
+diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c
+index c66cc05a68c454..473ec58f87a2eb 100644
+--- a/drivers/misc/lkdtm/bugs.c
++++ b/drivers/misc/lkdtm/bugs.c
+@@ -388,8 +388,8 @@ static void lkdtm_FAM_BOUNDS(void)
+
+ pr_err("FAIL: survived access of invalid flexible array member index!\n");
+
+- if (!__has_attribute(__counted_by__))
+- pr_warn("This is expected since this %s was built a compiler supporting __counted_by\n",
++ if (!IS_ENABLED(CONFIG_CC_HAS_COUNTED_BY))
++ pr_warn("This is expected since this %s was built with a compiler that does not support __counted_by\n",
+ lkdtm_kernel_info);
+ else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
+ pr_expected_config(CONFIG_UBSAN_TRAP);
+diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
+index 2a99ffb61f8c04..30b93dc938f1ae 100644
+--- a/drivers/mmc/host/mmc_spi.c
++++ b/drivers/mmc/host/mmc_spi.c
+@@ -223,10 +223,6 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
+ u8 leftover = 0;
+ unsigned short rotator;
+ int i;
+- char tag[32];
+-
+- snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s",
+- cmd->opcode, maptype(cmd));
+
+ /* Except for data block reads, the whole response will already
+ * be stored in the scratch buffer. It's somewhere after the
+@@ -379,8 +375,9 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
+ }
+
+ if (value < 0)
+- dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n",
+- tag, cmd->resp[0], cmd->resp[1]);
++ dev_dbg(&host->spi->dev,
++ " ... CMD%d response SPI_%s: resp %04x %08x\n",
++ cmd->opcode, maptype(cmd), cmd->resp[0], cmd->resp[1]);
+
+ /* disable chipselect on errors and some success cases */
+ if (value >= 0 && cs_on)
+diff --git a/drivers/mtd/hyperbus/rpc-if.c b/drivers/mtd/hyperbus/rpc-if.c
+index ef32fca5f785e3..e7a28f3316c3f2 100644
+--- a/drivers/mtd/hyperbus/rpc-if.c
++++ b/drivers/mtd/hyperbus/rpc-if.c
+@@ -154,20 +154,25 @@ static int rpcif_hb_probe(struct platform_device *pdev)
+ return error;
+ }
+
+-static int rpcif_hb_remove(struct platform_device *pdev)
++static void rpcif_hb_remove(struct platform_device *pdev)
+ {
+ struct rpcif_hyperbus *hyperbus = platform_get_drvdata(pdev);
+
+ hyperbus_unregister_device(&hyperbus->hbdev);
+
+ pm_runtime_disable(hyperbus->rpc.dev);
+-
+- return 0;
+ }
+
++static const struct platform_device_id rpc_if_hyperflash_id_table[] = {
++ { .name = "rpc-if-hyperflash" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(platform, rpc_if_hyperflash_id_table);
++
+ static struct platform_driver rpcif_platform_driver = {
+ .probe = rpcif_hb_probe,
+- .remove = rpcif_hb_remove,
++ .remove_new = rpcif_hb_remove,
++ .id_table = rpc_if_hyperflash_id_table,
+ .driver = {
+ .name = "rpc-if-hyperflash",
+ },
+diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c
+index 4d7dc8a9c37385..a22aab4ed4e8ab 100644
+--- a/drivers/mtd/nand/raw/atmel/pmecc.c
++++ b/drivers/mtd/nand/raw/atmel/pmecc.c
+@@ -362,7 +362,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
+ size = ALIGN(size, sizeof(s32));
+ size += (req->ecc.strength + 1) * sizeof(s32) * 3;
+
+- user = kzalloc(size, GFP_KERNEL);
++ user = devm_kzalloc(pmecc->dev, size, GFP_KERNEL);
+ if (!user)
+ return ERR_PTR(-ENOMEM);
+
+@@ -408,12 +408,6 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
+ }
+ EXPORT_SYMBOL_GPL(atmel_pmecc_create_user);
+
+-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user)
+-{
+- kfree(user);
+-}
+-EXPORT_SYMBOL_GPL(atmel_pmecc_destroy_user);
+-
+ static int get_strength(struct atmel_pmecc_user *user)
+ {
+ const int *strengths = user->pmecc->caps->strengths;
+diff --git a/drivers/mtd/nand/raw/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h
+index 7851c05126cf15..cc0c5af1f4f1ab 100644
+--- a/drivers/mtd/nand/raw/atmel/pmecc.h
++++ b/drivers/mtd/nand/raw/atmel/pmecc.h
+@@ -55,8 +55,6 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev);
+ struct atmel_pmecc_user *
+ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
+ struct atmel_pmecc_user_req *req);
+-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
+-
+ void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
+ int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
+ void atmel_pmecc_disable(struct atmel_pmecc_user *user);
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 1b0c6770c14e46..8d75a66775cb1f 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -89,7 +89,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor,
+ op->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto);
+
+ if (op->dummy.nbytes)
+- op->dummy.buswidth = spi_nor_get_protocol_addr_nbits(proto);
++ op->dummy.buswidth = spi_nor_get_protocol_data_nbits(proto);
+
+ if (op->data.nbytes)
+ op->data.buswidth = spi_nor_get_protocol_data_nbits(proto);
+diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
+index 709822fced867f..828b442735ee83 100644
+--- a/drivers/mtd/spi-nor/spansion.c
++++ b/drivers/mtd/spi-nor/spansion.c
+@@ -105,6 +105,7 @@ static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)
+ int ret;
+
+ if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
++ op.addr.nbytes = nor->addr_nbytes;
+ op.dummy.nbytes = params->rdsr_dummy;
+ op.data.nbytes = 2;
+ }
+diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
+index ae5abe492b52ab..adc47b87b38a5f 100644
+--- a/drivers/mtd/ubi/attach.c
++++ b/drivers/mtd/ubi/attach.c
+@@ -1447,7 +1447,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ return err;
+ }
+
+-static struct ubi_attach_info *alloc_ai(void)
++static struct ubi_attach_info *alloc_ai(const char *slab_name)
+ {
+ struct ubi_attach_info *ai;
+
+@@ -1461,7 +1461,7 @@ static struct ubi_attach_info *alloc_ai(void)
+ INIT_LIST_HEAD(&ai->alien);
+ INIT_LIST_HEAD(&ai->fastmap);
+ ai->volumes = RB_ROOT;
+- ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
++ ai->aeb_slab_cache = kmem_cache_create(slab_name,
+ sizeof(struct ubi_ainf_peb),
+ 0, 0, NULL);
+ if (!ai->aeb_slab_cache) {
+@@ -1491,7 +1491,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai)
+
+ err = -ENOMEM;
+
+- scan_ai = alloc_ai();
++ scan_ai = alloc_ai("ubi_aeb_slab_cache_fastmap");
+ if (!scan_ai)
+ goto out;
+
+@@ -1557,7 +1557,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
+ int err;
+ struct ubi_attach_info *ai;
+
+- ai = alloc_ai();
++ ai = alloc_ai("ubi_aeb_slab_cache");
+ if (!ai)
+ return -ENOMEM;
+
+@@ -1575,7 +1575,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
+ if (err > 0 || mtd_is_eccerr(err)) {
+ if (err != UBI_NO_FASTMAP) {
+ destroy_ai(ai);
+- ai = alloc_ai();
++ ai = alloc_ai("ubi_aeb_slab_cache");
+ if (!ai)
+ return -ENOMEM;
+
+@@ -1614,7 +1614,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
+ if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) {
+ struct ubi_attach_info *scan_ai;
+
+- scan_ai = alloc_ai();
++ scan_ai = alloc_ai("ubi_aeb_slab_cache_dbg_chk_fastmap");
+ if (!scan_ai) {
+ err = -ENOMEM;
+ goto out_wl;
+diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
+index 863f571f1adb54..79733163ab7d02 100644
+--- a/drivers/mtd/ubi/fastmap-wl.c
++++ b/drivers/mtd/ubi/fastmap-wl.c
+@@ -282,14 +282,27 @@ int ubi_wl_get_peb(struct ubi_device *ubi)
+ * WL sub-system.
+ *
+ * @ubi: UBI device description object
++ * @need_fill: whether to fill wear-leveling pool when no PEBs are found
+ */
+-static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi)
++static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi,
++ bool need_fill)
+ {
+ struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
+ int pnum;
+
+- if (pool->used == pool->size)
++ if (pool->used == pool->size) {
++ if (need_fill && !ubi->fm_work_scheduled) {
++ /*
++ * We cannot update the fastmap here because this
++ * function is called in atomic context.
++ * Let's fail here and refill/update it as soon as
++ * possible.
++ */
++ ubi->fm_work_scheduled = 1;
++ schedule_work(&ubi->fm_work);
++ }
+ return NULL;
++ }
+
+ pnum = pool->pebs[pool->used];
+ return ubi->lookuptbl[pnum];
+@@ -311,7 +324,7 @@ static bool need_wear_leveling(struct ubi_device *ubi)
+ if (!ubi->used.rb_node)
+ return false;
+
+- e = next_peb_for_wl(ubi);
++ e = next_peb_for_wl(ubi, false);
+ if (!e) {
+ if (!ubi->free.rb_node)
+ return false;
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index 26a214f016c184..886d44019401a8 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -671,7 +671,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
+ ubi_assert(!ubi->move_to_put);
+
+ #ifdef CONFIG_MTD_UBI_FASTMAP
+- if (!next_peb_for_wl(ubi) ||
++ if (!next_peb_for_wl(ubi, true) ||
+ #else
+ if (!ubi->free.rb_node ||
+ #endif
+@@ -834,7 +834,14 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
+ goto out_not_moved;
+ }
+ if (err == MOVE_RETRY) {
+- scrubbing = 1;
++ /*
++ * For source PEB:
++ * 1. The scrubbing is set for scrub type PEB, it will
++ * be put back into ubi->scrub list.
++ * 2. Non-scrub type PEB will be put back into ubi->used
++ * list.
++ */
++ keep = 1;
+ dst_leb_clean = 1;
+ goto out_not_moved;
+ }
+diff --git a/drivers/mtd/ubi/wl.h b/drivers/mtd/ubi/wl.h
+index 5ebe374a08aed9..1d83e552533a5d 100644
+--- a/drivers/mtd/ubi/wl.h
++++ b/drivers/mtd/ubi/wl.h
+@@ -5,7 +5,8 @@
+ static void update_fastmap_work_fn(struct work_struct *wrk);
+ static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root);
+ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
+-static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi);
++static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi,
++ bool need_fill);
+ static bool need_wear_leveling(struct ubi_device *ubi);
+ static void ubi_fastmap_close(struct ubi_device *ubi);
+ static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count)
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 58a7bb75506a3e..c440f4d8d43a27 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -7597,7 +7597,6 @@ static int __bnxt_hwrm_ptp_qcfg(struct bnxt *bp)
+ struct hwrm_port_mac_ptp_qcfg_output *resp;
+ struct hwrm_port_mac_ptp_qcfg_input *req;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+- bool phc_cfg;
+ u8 flags;
+ int rc;
+
+@@ -7640,8 +7639,9 @@ static int __bnxt_hwrm_ptp_qcfg(struct bnxt *bp)
+ rc = -ENODEV;
+ goto exit;
+ }
+- phc_cfg = (flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_RTC_CONFIGURED) != 0;
+- rc = bnxt_ptp_init(bp, phc_cfg);
++ ptp->rtc_configured =
++ (flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_RTC_CONFIGURED) != 0;
++ rc = bnxt_ptp_init(bp);
+ if (rc)
+ netdev_warn(bp->dev, "PTP initialization failed.\n");
+ exit:
+@@ -13857,6 +13857,7 @@ static void bnxt_shutdown(struct pci_dev *pdev)
+ if (netif_running(dev))
+ dev_close(dev);
+
++ bnxt_ptp_clear(bp);
+ bnxt_clear_int_mode(bp);
+ pci_disable_device(pdev);
+
+@@ -13883,6 +13884,7 @@ static int bnxt_suspend(struct device *device)
+ rc = bnxt_close(dev);
+ }
+ bnxt_hwrm_func_drv_unrgtr(bp);
++ bnxt_ptp_clear(bp);
+ pci_disable_device(bp->pdev);
+ bnxt_free_ctx_mem(bp);
+ kfree(bp->ctx);
+@@ -13926,6 +13928,10 @@ static int bnxt_resume(struct device *device)
+ goto resume_exit;
+ }
+
++ if (bnxt_ptp_init(bp)) {
++ kfree(bp->ptp_cfg);
++ bp->ptp_cfg = NULL;
++ }
+ bnxt_get_wol_settings(bp);
+ if (netif_running(dev)) {
+ rc = bnxt_open(dev);
+@@ -14102,8 +14108,12 @@ static void bnxt_io_resume(struct pci_dev *pdev)
+ rtnl_lock();
+
+ err = bnxt_hwrm_func_qcaps(bp);
+- if (!err && netif_running(netdev))
+- err = bnxt_open(netdev);
++ if (!err) {
++ if (netif_running(netdev))
++ err = bnxt_open(netdev);
++ else
++ err = bnxt_reserve_rings(bp, true);
++ }
+
+ bnxt_ulp_start(bp, err);
+ if (!err) {
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+index 6e3da3362bd617..bbe8657f6545b3 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+@@ -922,7 +922,7 @@ static void bnxt_ptp_free(struct bnxt *bp)
+ }
+ }
+
+-int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
++int bnxt_ptp_init(struct bnxt *bp)
+ {
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ int rc;
+@@ -944,7 +944,7 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
+
+ if (BNXT_PTP_USE_RTC(bp)) {
+ bnxt_ptp_timecounter_init(bp, false);
+- rc = bnxt_ptp_init_rtc(bp, phc_cfg);
++ rc = bnxt_ptp_init_rtc(bp, ptp->rtc_configured);
+ if (rc)
+ goto out;
+ } else {
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
+index 34162e07a1195c..7d6a215b10b1fa 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
+@@ -115,6 +115,7 @@ struct bnxt_ptp_cfg {
+ BNXT_PTP_MSG_PDELAY_REQ | \
+ BNXT_PTP_MSG_PDELAY_RESP)
+ u8 tx_tstamp_en:1;
++ u8 rtc_configured:1;
+ int rx_filter;
+ u32 tstamp_filters;
+
+@@ -145,6 +146,6 @@ int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb);
+ int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts);
+ void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns);
+ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg);
+-int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg);
++int bnxt_ptp_init(struct bnxt *bp);
+ void bnxt_ptp_clear(struct bnxt *bp);
+ #endif
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index f1c8ff5b63acde..7f74e5e106d9d4 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -17731,6 +17731,9 @@ static int tg3_init_one(struct pci_dev *pdev,
+ } else
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
+
++ if (tg3_asic_rev(tp) == ASIC_REV_57766)
++ persist_dma_mask = DMA_BIT_MASK(31);
++
+ /* Configure DMA attributes. */
+ if (dma_mask > DMA_BIT_MASK(32)) {
+ err = dma_set_mask(&pdev->dev, dma_mask);
+diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+index 6c6f267dcccc3f..9f7268bb2ee3b4 100644
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+@@ -479,6 +479,9 @@ static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg)
+ if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)
+ vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES;
+
++ if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC)
++ vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_CRC;
++
+ if (vf->driver_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
+ vfres->vf_cap_flags |= VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
+
+@@ -1642,8 +1645,8 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
+
+ /* copy Tx queue info from VF into VSI */
+ if (qpi->txq.ring_len > 0) {
+- vsi->tx_rings[i]->dma = qpi->txq.dma_ring_addr;
+- vsi->tx_rings[i]->count = qpi->txq.ring_len;
++ vsi->tx_rings[q_idx]->dma = qpi->txq.dma_ring_addr;
++ vsi->tx_rings[q_idx]->count = qpi->txq.ring_len;
+
+ /* Disable any existing queue first */
+ if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx))
+@@ -1652,7 +1655,7 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
+ /* Configure a queue with the requested settings */
+ if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) {
+ dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n",
+- vf->vf_id, i);
++ vf->vf_id, q_idx);
+ goto error_param;
+ }
+ }
+@@ -1660,17 +1663,28 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
+ /* copy Rx queue info from VF into VSI */
+ if (qpi->rxq.ring_len > 0) {
+ u16 max_frame_size = ice_vc_get_max_frame_size(vf);
++ struct ice_rx_ring *ring = vsi->rx_rings[q_idx];
+ u32 rxdid;
+
+- vsi->rx_rings[i]->dma = qpi->rxq.dma_ring_addr;
+- vsi->rx_rings[i]->count = qpi->rxq.ring_len;
++ ring->dma = qpi->rxq.dma_ring_addr;
++ ring->count = qpi->rxq.ring_len;
++
++ if (qpi->rxq.crc_disable &&
++ !(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC)) {
++ goto error_param;
++ }
++
++ if (qpi->rxq.crc_disable)
++ ring->flags |= ICE_RX_FLAGS_CRC_STRIP_DIS;
++ else
++ ring->flags &= ~ICE_RX_FLAGS_CRC_STRIP_DIS;
+
+ if (qpi->rxq.databuffer_size != 0 &&
+ (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
+ qpi->rxq.databuffer_size < 1024))
+ goto error_param;
+ vsi->rx_buf_len = qpi->rxq.databuffer_size;
+- vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len;
++ ring->rx_buf_len = vsi->rx_buf_len;
+ if (qpi->rxq.max_pkt_size > max_frame_size ||
+ qpi->rxq.max_pkt_size < 64)
+ goto error_param;
+@@ -1685,7 +1699,7 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
+
+ if (ice_vsi_cfg_single_rxq(vsi, q_idx)) {
+ dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n",
+- vf->vf_id, i);
++ vf->vf_id, q_idx);
+ goto error_param;
+ }
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+index 2539c985f695a7..52792546fe00dd 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+@@ -24,6 +24,8 @@
+ #define DRV_NAME "Marvell-CGX/RPM"
+ #define DRV_STRING "Marvell CGX/RPM Driver"
+
++#define CGX_RX_STAT_GLOBAL_INDEX 9
++
+ static LIST_HEAD(cgx_list);
+
+ /* Convert firmware speed encoding to user format(Mbps) */
+@@ -110,6 +112,11 @@ struct mac_ops *get_mac_ops(void *cgxd)
+ return ((struct cgx *)cgxd)->mac_ops;
+ }
+
++u32 cgx_get_fifo_len(void *cgxd)
++{
++ return ((struct cgx *)cgxd)->fifo_len;
++}
++
+ void cgx_write(struct cgx *cgx, u64 lmac, u64 offset, u64 val)
+ {
+ writeq(val, cgx->reg_base + (lmac << cgx->mac_ops->lmac_offset) +
+@@ -207,6 +214,24 @@ u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id)
+ return (cfg & CMR_P2X_SEL_MASK) >> CMR_P2X_SEL_SHIFT;
+ }
+
++static u8 cgx_get_nix_resetbit(struct cgx *cgx)
++{
++ int first_lmac;
++ u8 p2x;
++
++ /* non 98XX silicons supports only NIX0 block */
++ if (cgx->pdev->subsystem_device != PCI_SUBSYS_DEVID_98XX)
++ return CGX_NIX0_RESET;
++
++ first_lmac = find_first_bit(&cgx->lmac_bmap, cgx->max_lmac_per_mac);
++ p2x = cgx_lmac_get_p2x(cgx->cgx_id, first_lmac);
++
++ if (p2x == CMR_P2X_SEL_NIX1)
++ return CGX_NIX1_RESET;
++ else
++ return CGX_NIX0_RESET;
++}
++
+ /* Ensure the required lock for event queue(where asynchronous events are
+ * posted) is acquired before calling this API. Else an asynchronous event(with
+ * latest link status) can reach the destination before this function returns
+@@ -499,7 +524,7 @@ static u32 cgx_get_lmac_fifo_len(void *cgxd, int lmac_id)
+ u8 num_lmacs;
+ u32 fifo_len;
+
+- fifo_len = cgx->mac_ops->fifo_len;
++ fifo_len = cgx->fifo_len;
+ num_lmacs = cgx->mac_ops->get_nr_lmacs(cgx);
+
+ switch (num_lmacs) {
+@@ -701,6 +726,30 @@ u64 cgx_features_get(void *cgxd)
+ return ((struct cgx *)cgxd)->hw_features;
+ }
+
++int cgx_stats_reset(void *cgxd, int lmac_id)
++{
++ struct cgx *cgx = cgxd;
++ int stat_id;
++
++ if (!is_lmac_valid(cgx, lmac_id))
++ return -ENODEV;
++
++ for (stat_id = 0 ; stat_id < CGX_RX_STATS_COUNT; stat_id++) {
++ if (stat_id >= CGX_RX_STAT_GLOBAL_INDEX)
++ /* pass lmac as 0 for CGX_CMR_RX_STAT9-12 */
++ cgx_write(cgx, 0,
++ (CGXX_CMRX_RX_STAT0 + (stat_id * 8)), 0);
++ else
++ cgx_write(cgx, lmac_id,
++ (CGXX_CMRX_RX_STAT0 + (stat_id * 8)), 0);
++ }
++
++ for (stat_id = 0 ; stat_id < CGX_TX_STATS_COUNT; stat_id++)
++ cgx_write(cgx, lmac_id, CGXX_CMRX_TX_STAT0 + (stat_id * 8), 0);
++
++ return 0;
++}
++
+ static int cgx_set_fec_stats_count(struct cgx_link_user_info *linfo)
+ {
+ if (!linfo->fec)
+@@ -1695,6 +1744,8 @@ static int cgx_lmac_init(struct cgx *cgx)
+ lmac->lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac->lmac_id);
+ }
+
++ /* Start X2P reset on given MAC block */
++ cgx->mac_ops->mac_x2p_reset(cgx, true);
+ return cgx_lmac_verify_fwi_version(cgx);
+
+ err_bitmap_free:
+@@ -1740,7 +1791,7 @@ static void cgx_populate_features(struct cgx *cgx)
+ u64 cfg;
+
+ cfg = cgx_read(cgx, 0, CGX_CONST);
+- cgx->mac_ops->fifo_len = FIELD_GET(CGX_CONST_RXFIFO_SIZE, cfg);
++ cgx->fifo_len = FIELD_GET(CGX_CONST_RXFIFO_SIZE, cfg);
+ cgx->max_lmac_per_mac = FIELD_GET(CGX_CONST_MAX_LMACS, cfg);
+
+ if (is_dev_rpm(cgx))
+@@ -1760,6 +1811,45 @@ static u8 cgx_get_rxid_mapoffset(struct cgx *cgx)
+ return 0x60;
+ }
+
++static void cgx_x2p_reset(void *cgxd, bool enable)
++{
++ struct cgx *cgx = cgxd;
++ int lmac_id;
++ u64 cfg;
++
++ if (enable) {
++ for_each_set_bit(lmac_id, &cgx->lmac_bmap, cgx->max_lmac_per_mac)
++ cgx->mac_ops->mac_enadis_rx(cgx, lmac_id, false);
++
++ usleep_range(1000, 2000);
++
++ cfg = cgx_read(cgx, 0, CGXX_CMR_GLOBAL_CONFIG);
++ cfg |= cgx_get_nix_resetbit(cgx) | CGX_NSCI_DROP;
++ cgx_write(cgx, 0, CGXX_CMR_GLOBAL_CONFIG, cfg);
++ } else {
++ cfg = cgx_read(cgx, 0, CGXX_CMR_GLOBAL_CONFIG);
++ cfg &= ~(cgx_get_nix_resetbit(cgx) | CGX_NSCI_DROP);
++ cgx_write(cgx, 0, CGXX_CMR_GLOBAL_CONFIG, cfg);
++ }
++}
++
++static int cgx_enadis_rx(void *cgxd, int lmac_id, bool enable)
++{
++ struct cgx *cgx = cgxd;
++ u64 cfg;
++
++ if (!is_lmac_valid(cgx, lmac_id))
++ return -ENODEV;
++
++ cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG);
++ if (enable)
++ cfg |= DATA_PKT_RX_EN;
++ else
++ cfg &= ~DATA_PKT_RX_EN;
++ cgx_write(cgx, lmac_id, CGXX_CMRX_CFG, cfg);
++ return 0;
++}
++
+ static struct mac_ops cgx_mac_ops = {
+ .name = "cgx",
+ .csr_offset = 0,
+@@ -1790,6 +1880,9 @@ static struct mac_ops cgx_mac_ops = {
+ .pfc_config = cgx_lmac_pfc_config,
+ .mac_get_pfc_frm_cfg = cgx_lmac_get_pfc_frm_cfg,
+ .mac_reset = cgx_lmac_reset,
++ .mac_stats_reset = cgx_stats_reset,
++ .mac_x2p_reset = cgx_x2p_reset,
++ .mac_enadis_rx = cgx_enadis_rx,
+ };
+
+ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+index 6f7d1dee58308c..1cf12e5c7da873 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+@@ -32,6 +32,10 @@
+ #define CGX_LMAC_TYPE_MASK 0xF
+ #define CGXX_CMRX_INT 0x040
+ #define FW_CGX_INT BIT_ULL(1)
++#define CGXX_CMR_GLOBAL_CONFIG 0x08
++#define CGX_NIX0_RESET BIT_ULL(2)
++#define CGX_NIX1_RESET BIT_ULL(3)
++#define CGX_NSCI_DROP BIT_ULL(9)
+ #define CGXX_CMRX_INT_ENA_W1S 0x058
+ #define CGXX_CMRX_RX_ID_MAP 0x060
+ #define CGXX_CMRX_RX_STAT0 0x070
+@@ -141,6 +145,7 @@ int cgx_lmac_evh_register(struct cgx_event_cb *cb, void *cgxd, int lmac_id);
+ int cgx_lmac_evh_unregister(void *cgxd, int lmac_id);
+ int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat);
+ int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat);
++int cgx_stats_reset(void *cgxd, int lmac_id);
+ int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
+ int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable);
+ int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
+@@ -184,4 +189,5 @@ int cgx_lmac_get_pfc_frm_cfg(void *cgxd, int lmac_id, u8 *tx_pause,
+ int verify_lmac_fc_cfg(void *cgxd, int lmac_id, u8 tx_pause, u8 rx_pause,
+ int pfvf_idx);
+ int cgx_lmac_reset(void *cgxd, int lmac_id, u8 pf_req_flr);
++u32 cgx_get_fifo_len(void *cgxd);
+ #endif /* CGX_H */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h b/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
+index 0b4cba03f2e837..6180e68e1765a7 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
+@@ -72,7 +72,6 @@ struct mac_ops {
+ u8 irq_offset;
+ u8 int_ena_bit;
+ u8 lmac_fwi;
+- u32 fifo_len;
+ bool non_contiguous_serdes_lane;
+ /* RPM & CGX differs in number of Receive/transmit stats */
+ u8 rx_stats_cnt;
+@@ -132,6 +131,9 @@ struct mac_ops {
+ /* FEC stats */
+ int (*get_fec_stats)(void *cgxd, int lmac_id,
+ struct cgx_fec_stats_rsp *rsp);
++ int (*mac_stats_reset)(void *cgxd, int lmac_id);
++ void (*mac_x2p_reset)(void *cgxd, bool enable);
++ int (*mac_enadis_rx)(void *cgxd, int lmac_id, bool enable);
+ };
+
+ struct cgx {
+@@ -141,6 +143,10 @@ struct cgx {
+ u8 lmac_count;
+ /* number of LMACs per MAC could be 4 or 8 */
+ u8 max_lmac_per_mac;
++ /* length of fifo varies depending on the number
++ * of LMACS
++ */
++ u32 fifo_len;
+ #define MAX_LMAC_COUNT 8
+ struct lmac *lmac_idmap[MAX_LMAC_COUNT];
+ struct work_struct cgx_cmd_work;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+index e883c0929b1a9b..b4b23e475c95f5 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+@@ -174,6 +174,7 @@ M(CGX_FEC_STATS, 0x217, cgx_fec_stats, msg_req, cgx_fec_stats_rsp) \
+ M(CGX_SET_LINK_MODE, 0x218, cgx_set_link_mode, cgx_set_link_mode_req,\
+ cgx_set_link_mode_rsp) \
+ M(CGX_GET_PHY_FEC_STATS, 0x219, cgx_get_phy_fec_stats, msg_req, msg_rsp) \
++M(CGX_STATS_RST, 0x21A, cgx_stats_rst, msg_req, msg_rsp) \
+ M(CGX_FEATURES_GET, 0x21B, cgx_features_get, msg_req, \
+ cgx_features_info_msg) \
+ M(RPM_STATS, 0x21C, rpm_stats, msg_req, rpm_stats_rsp) \
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
+index 76218f1cb45958..2e9945446199ec 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
+@@ -38,6 +38,9 @@ static struct mac_ops rpm_mac_ops = {
+ .pfc_config = rpm_lmac_pfc_config,
+ .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg,
+ .mac_reset = rpm_lmac_reset,
++ .mac_stats_reset = rpm_stats_reset,
++ .mac_x2p_reset = rpm_x2p_reset,
++ .mac_enadis_rx = rpm_enadis_rx,
+ };
+
+ static struct mac_ops rpm2_mac_ops = {
+@@ -70,6 +73,9 @@ static struct mac_ops rpm2_mac_ops = {
+ .pfc_config = rpm_lmac_pfc_config,
+ .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg,
+ .mac_reset = rpm_lmac_reset,
++ .mac_stats_reset = rpm_stats_reset,
++ .mac_x2p_reset = rpm_x2p_reset,
++ .mac_enadis_rx = rpm_enadis_rx,
+ };
+
+ bool is_dev_rpm2(void *rpmd)
+@@ -443,6 +449,21 @@ int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat)
+ return 0;
+ }
+
++int rpm_stats_reset(void *rpmd, int lmac_id)
++{
++ rpm_t *rpm = rpmd;
++ u64 cfg;
++
++ if (!is_lmac_valid(rpm, lmac_id))
++ return -ENODEV;
++
++ cfg = rpm_read(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL);
++ cfg |= RPMX_CMD_CLEAR_TX | RPMX_CMD_CLEAR_RX | BIT_ULL(lmac_id);
++ rpm_write(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL, cfg);
++
++ return 0;
++}
++
+ u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
+ {
+ rpm_t *rpm = rpmd;
+@@ -450,7 +471,7 @@ u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
+ int err;
+
+ req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_LINK_STS, req);
+- err = cgx_fwi_cmd_generic(req, &resp, rpm, 0);
++ err = cgx_fwi_cmd_generic(req, &resp, rpm, lmac_id);
+ if (!err)
+ return FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, resp);
+ return err;
+@@ -463,7 +484,7 @@ u32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id)
+ u8 num_lmacs;
+ u32 fifo_len;
+
+- fifo_len = rpm->mac_ops->fifo_len;
++ fifo_len = rpm->fifo_len;
+ num_lmacs = rpm->mac_ops->get_nr_lmacs(rpm);
+
+ switch (num_lmacs) {
+@@ -516,9 +537,9 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id)
+ */
+ max_lmac = (rpm_read(rpm, 0, CGX_CONST) >> 24) & 0xFF;
+ if (max_lmac > 4)
+- fifo_len = rpm->mac_ops->fifo_len / 2;
++ fifo_len = rpm->fifo_len / 2;
+ else
+- fifo_len = rpm->mac_ops->fifo_len;
++ fifo_len = rpm->fifo_len;
+
+ if (lmac_id < 4) {
+ num_lmacs = hweight8(lmac_info & 0xF);
+@@ -682,46 +703,51 @@ int rpm_get_fec_stats(void *rpmd, int lmac_id, struct cgx_fec_stats_rsp *rsp)
+ if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_NONE)
+ return 0;
+
++ /* latched registers FCFECX_CW_HI/RSFEC_STAT_FAST_DATA_HI_CDC are common
++ * for all counters. Acquire lock to ensure serialized reads
++ */
++ mutex_lock(&rpm->lock);
+ if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_BASER) {
+- val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_CCW_LO);
+- val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI);
++ val_lo = rpm_read(rpm, 0, RPMX_MTI_FCFECX_VL0_CCW_LO(lmac_id));
++ val_hi = rpm_read(rpm, 0, RPMX_MTI_FCFECX_CW_HI(lmac_id));
+ rsp->fec_corr_blks = (val_hi << 16 | val_lo);
+
+- val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_NCCW_LO);
+- val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI);
++ val_lo = rpm_read(rpm, 0, RPMX_MTI_FCFECX_VL0_NCCW_LO(lmac_id));
++ val_hi = rpm_read(rpm, 0, RPMX_MTI_FCFECX_CW_HI(lmac_id));
+ rsp->fec_uncorr_blks = (val_hi << 16 | val_lo);
+
+ /* 50G uses 2 Physical serdes lines */
+ if (rpm->lmac_idmap[lmac_id]->link_info.lmac_type_id ==
+ LMAC_MODE_50G_R) {
+- val_lo = rpm_read(rpm, lmac_id,
+- RPMX_MTI_FCFECX_VL1_CCW_LO);
+- val_hi = rpm_read(rpm, lmac_id,
+- RPMX_MTI_FCFECX_CW_HI);
++ val_lo = rpm_read(rpm, 0,
++ RPMX_MTI_FCFECX_VL1_CCW_LO(lmac_id));
++ val_hi = rpm_read(rpm, 0,
++ RPMX_MTI_FCFECX_CW_HI(lmac_id));
+ rsp->fec_corr_blks += (val_hi << 16 | val_lo);
+
+- val_lo = rpm_read(rpm, lmac_id,
+- RPMX_MTI_FCFECX_VL1_NCCW_LO);
+- val_hi = rpm_read(rpm, lmac_id,
+- RPMX_MTI_FCFECX_CW_HI);
++ val_lo = rpm_read(rpm, 0,
++ RPMX_MTI_FCFECX_VL1_NCCW_LO(lmac_id));
++ val_hi = rpm_read(rpm, 0,
++ RPMX_MTI_FCFECX_CW_HI(lmac_id));
+ rsp->fec_uncorr_blks += (val_hi << 16 | val_lo);
+ }
+ } else {
+ /* enable RS-FEC capture */
+- cfg = rpm_read(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL);
++ cfg = rpm_read(rpm, 0, RPMX_MTI_RSFEC_STAT_STATN_CONTROL);
+ cfg |= RPMX_RSFEC_RX_CAPTURE | BIT(lmac_id);
+- rpm_write(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL, cfg);
++ rpm_write(rpm, 0, RPMX_MTI_RSFEC_STAT_STATN_CONTROL, cfg);
+
+ val_lo = rpm_read(rpm, 0,
+ RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_2);
+- val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC);
++ val_hi = rpm_read(rpm, 0, RPMX_MTI_RSFEC_STAT_FAST_DATA_HI_CDC);
+ rsp->fec_corr_blks = (val_hi << 32 | val_lo);
+
+ val_lo = rpm_read(rpm, 0,
+ RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_3);
+- val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC);
++ val_hi = rpm_read(rpm, 0, RPMX_MTI_RSFEC_STAT_FAST_DATA_HI_CDC);
+ rsp->fec_uncorr_blks = (val_hi << 32 | val_lo);
+ }
++ mutex_unlock(&rpm->lock);
+
+ return 0;
+ }
+@@ -746,3 +772,41 @@ int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr)
+
+ return 0;
+ }
++
++void rpm_x2p_reset(void *rpmd, bool enable)
++{
++ rpm_t *rpm = rpmd;
++ int lmac_id;
++ u64 cfg;
++
++ if (enable) {
++ for_each_set_bit(lmac_id, &rpm->lmac_bmap, rpm->max_lmac_per_mac)
++ rpm->mac_ops->mac_enadis_rx(rpm, lmac_id, false);
++
++ usleep_range(1000, 2000);
++
++ cfg = rpm_read(rpm, 0, RPMX_CMR_GLOBAL_CFG);
++ rpm_write(rpm, 0, RPMX_CMR_GLOBAL_CFG, cfg | RPM_NIX0_RESET);
++ } else {
++ cfg = rpm_read(rpm, 0, RPMX_CMR_GLOBAL_CFG);
++ cfg &= ~RPM_NIX0_RESET;
++ rpm_write(rpm, 0, RPMX_CMR_GLOBAL_CFG, cfg);
++ }
++}
++
++int rpm_enadis_rx(void *rpmd, int lmac_id, bool enable)
++{
++ rpm_t *rpm = rpmd;
++ u64 cfg;
++
++ if (!is_lmac_valid(rpm, lmac_id))
++ return -ENODEV;
++
++ cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG);
++ if (enable)
++ cfg |= RPM_RX_EN;
++ else
++ cfg &= ~RPM_RX_EN;
++ rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg);
++ return 0;
++}
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rpm.h b/drivers/net/ethernet/marvell/octeontx2/af/rpm.h
+index b79cfbc6f87705..b8d3972e096aed 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rpm.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rpm.h
+@@ -17,6 +17,8 @@
+
+ /* Registers */
+ #define RPMX_CMRX_CFG 0x00
++#define RPMX_CMR_GLOBAL_CFG 0x08
++#define RPM_NIX0_RESET BIT_ULL(3)
+ #define RPMX_RX_TS_PREPEND BIT_ULL(22)
+ #define RPMX_TX_PTP_1S_SUPPORT BIT_ULL(17)
+ #define RPMX_CMRX_RX_ID_MAP 0x80
+@@ -84,14 +86,18 @@
+ /* FEC stats */
+ #define RPMX_MTI_STAT_STATN_CONTROL 0x10018
+ #define RPMX_MTI_STAT_DATA_HI_CDC 0x10038
+-#define RPMX_RSFEC_RX_CAPTURE BIT_ULL(27)
++#define RPMX_RSFEC_RX_CAPTURE BIT_ULL(28)
++#define RPMX_CMD_CLEAR_RX BIT_ULL(30)
++#define RPMX_CMD_CLEAR_TX BIT_ULL(31)
++#define RPMX_MTI_RSFEC_STAT_STATN_CONTROL 0x40018
++#define RPMX_MTI_RSFEC_STAT_FAST_DATA_HI_CDC 0x40000
+ #define RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_2 0x40050
+ #define RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_3 0x40058
+-#define RPMX_MTI_FCFECX_VL0_CCW_LO 0x38618
+-#define RPMX_MTI_FCFECX_VL0_NCCW_LO 0x38620
+-#define RPMX_MTI_FCFECX_VL1_CCW_LO 0x38628
+-#define RPMX_MTI_FCFECX_VL1_NCCW_LO 0x38630
+-#define RPMX_MTI_FCFECX_CW_HI 0x38638
++#define RPMX_MTI_FCFECX_VL0_CCW_LO(a) (0x38618 + ((a) * 0x40))
++#define RPMX_MTI_FCFECX_VL0_NCCW_LO(a) (0x38620 + ((a) * 0x40))
++#define RPMX_MTI_FCFECX_VL1_CCW_LO(a) (0x38628 + ((a) * 0x40))
++#define RPMX_MTI_FCFECX_VL1_NCCW_LO(a) (0x38630 + ((a) * 0x40))
++#define RPMX_MTI_FCFECX_CW_HI(a) (0x38638 + ((a) * 0x40))
+
+ /* CN10KB CSR Declaration */
+ #define RPM2_CMRX_SW_INT 0x1b0
+@@ -134,4 +140,7 @@ int rpm2_get_nr_lmacs(void *rpmd);
+ bool is_dev_rpm2(void *rpmd);
+ int rpm_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
+ int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr);
++int rpm_stats_reset(void *rpmd, int lmac_id);
++void rpm_x2p_reset(void *rpmd, bool enable);
++int rpm_enadis_rx(void *rpmd, int lmac_id, bool enable);
+ #endif /* RPM_H */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+index 5906f5f8d19041..5241737222236a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+@@ -1157,6 +1157,7 @@ static int rvu_setup_hw_resources(struct rvu *rvu)
+ }
+
+ rvu_program_channels(rvu);
++ cgx_start_linkup(rvu);
+
+ err = rvu_mcs_init(rvu);
+ if (err) {
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+index e81cfcaf9ce4fe..a607c7294b0c59 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+@@ -912,6 +912,7 @@ int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_
+ int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause);
+ void rvu_mac_reset(struct rvu *rvu, u16 pcifunc);
+ u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
++void cgx_start_linkup(struct rvu *rvu);
+ int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
+ int type);
+ bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+index 19075f217d00c5..d14cf2a9d207ed 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+@@ -349,6 +349,7 @@ static void rvu_cgx_wq_destroy(struct rvu *rvu)
+
+ int rvu_cgx_init(struct rvu *rvu)
+ {
++ struct mac_ops *mac_ops;
+ int cgx, err;
+ void *cgxd;
+
+@@ -375,6 +376,15 @@ int rvu_cgx_init(struct rvu *rvu)
+ if (err)
+ return err;
+
++ /* Clear X2P reset on all MAC blocks */
++ for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++) {
++ cgxd = rvu_cgx_pdata(cgx, rvu);
++ if (!cgxd)
++ continue;
++ mac_ops = get_mac_ops(cgxd);
++ mac_ops->mac_x2p_reset(cgxd, false);
++ }
++
+ /* Register for CGX events */
+ err = cgx_lmac_event_handler_init(rvu);
+ if (err)
+@@ -382,10 +392,26 @@ int rvu_cgx_init(struct rvu *rvu)
+
+ mutex_init(&rvu->cgx_cfg_lock);
+
+- /* Ensure event handler registration is completed, before
+- * we turn on the links
+- */
+- mb();
++ return 0;
++}
++
++void cgx_start_linkup(struct rvu *rvu)
++{
++ unsigned long lmac_bmap;
++ struct mac_ops *mac_ops;
++ int cgx, lmac, err;
++ void *cgxd;
++
++ /* Enable receive on all LMACS */
++ for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
++ cgxd = rvu_cgx_pdata(cgx, rvu);
++ if (!cgxd)
++ continue;
++ mac_ops = get_mac_ops(cgxd);
++ lmac_bmap = cgx_get_lmac_bmap(cgxd);
++ for_each_set_bit(lmac, &lmac_bmap, rvu->hw->lmac_per_cgx)
++ mac_ops->mac_enadis_rx(cgxd, lmac, true);
++ }
+
+ /* Do link up for all CGX ports */
+ for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
+@@ -398,8 +424,6 @@ int rvu_cgx_init(struct rvu *rvu)
+ "Link up process failed to start on cgx %d\n",
+ cgx);
+ }
+-
+- return 0;
+ }
+
+ int rvu_cgx_exit(struct rvu *rvu)
+@@ -604,6 +628,35 @@ int rvu_mbox_handler_rpm_stats(struct rvu *rvu, struct msg_req *req,
+ return rvu_lmac_get_stats(rvu, req, (void *)rsp);
+ }
+
++int rvu_mbox_handler_cgx_stats_rst(struct rvu *rvu, struct msg_req *req,
++ struct msg_rsp *rsp)
++{
++ int pf = rvu_get_pf(req->hdr.pcifunc);
++ struct rvu_pfvf *parent_pf;
++ struct mac_ops *mac_ops;
++ u8 cgx_idx, lmac;
++ void *cgxd;
++
++ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
++ return LMAC_AF_ERR_PERM_DENIED;
++
++ parent_pf = &rvu->pf[pf];
++ /* To ensure reset cgx stats won't affect VF stats,
++ * check if it used by only PF interface.
++ * If not, return
++ */
++ if (parent_pf->cgx_users > 1) {
++ dev_info(rvu->dev, "CGX busy, could not reset statistics\n");
++ return 0;
++ }
++
++ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
++ cgxd = rvu_cgx_pdata(cgx_idx, rvu);
++ mac_ops = get_mac_ops(cgxd);
++
++ return mac_ops->mac_stats_reset(cgxd, lmac);
++}
++
+ int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
+ struct msg_req *req,
+ struct cgx_fec_stats_rsp *rsp)
+@@ -895,13 +948,12 @@ int rvu_mbox_handler_cgx_features_get(struct rvu *rvu,
+
+ u32 rvu_cgx_get_fifolen(struct rvu *rvu)
+ {
+- struct mac_ops *mac_ops;
+- u32 fifo_len;
++ void *cgxd = rvu_first_cgx_pdata(rvu);
+
+- mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
+- fifo_len = mac_ops ? mac_ops->fifo_len : 0;
++ if (!cgxd)
++ return 0;
+
+- return fifo_len;
++ return cgx_get_fifo_len(cgxd);
+ }
+
+ u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
+index c1c99d7054f87f..7417087b6db597 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
+@@ -203,6 +203,11 @@ int cn10k_alloc_leaf_profile(struct otx2_nic *pfvf, u16 *leaf)
+
+ rsp = (struct nix_bandprof_alloc_rsp *)
+ otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ rc = PTR_ERR(rsp);
++ goto out;
++ }
++
+ if (!rsp->prof_count[BAND_PROF_LEAF_LAYER]) {
+ rc = -EIO;
+ goto out;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index b3064377510ed9..47adccf7a77765 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -1837,6 +1837,10 @@ u16 otx2_get_max_mtu(struct otx2_nic *pfvf)
+ if (!rc) {
+ rsp = (struct nix_hw_info *)
+ otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ rc = PTR_ERR(rsp);
++ goto out;
++ }
+
+ /* HW counts VLAN insertion bytes (8 for double tag)
+ * irrespective of whether SQE is requesting to insert VLAN
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index 7e16a341ec588f..c5de3ba33e2f0e 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -961,6 +961,7 @@ void otx2_get_mac_from_af(struct net_device *netdev);
+ void otx2_config_irq_coalescing(struct otx2_nic *pfvf, int qidx);
+ int otx2_config_pause_frm(struct otx2_nic *pfvf);
+ void otx2_setup_segmentation(struct otx2_nic *pfvf);
++int otx2_reset_mac_stats(struct otx2_nic *pfvf);
+
+ /* RVU block related APIs */
+ int otx2_attach_npa_nix(struct otx2_nic *pfvf);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
+index aa01110f04a339..294fba58b67095 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
+@@ -315,6 +315,11 @@ int otx2_config_priority_flow_ctrl(struct otx2_nic *pfvf)
+ if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
+ rsp = (struct cgx_pfc_rsp *)
+ otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ err = PTR_ERR(rsp);
++ goto unlock;
++ }
++
+ if (req->rx_pause != rsp->rx_pause || req->tx_pause != rsp->tx_pause) {
+ dev_warn(pfvf->dev,
+ "Failed to config PFC\n");
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
+index 80d853b343f98f..2046dd0da00d85 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
+@@ -28,6 +28,11 @@ static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
+ if (!err) {
+ rsp = (struct cgx_mac_addr_add_rsp *)
+ otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ mutex_unlock(&pf->mbox.lock);
++ return PTR_ERR(rsp);
++ }
++
+ *dmac_index = rsp->index;
+ }
+
+@@ -200,6 +205,10 @@ int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u32 bit_pos)
+
+ rsp = (struct cgx_mac_addr_update_rsp *)
+ otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ rc = PTR_ERR(rsp);
++ goto out;
++ }
+
+ pf->flow_cfg->bmap_to_dmacindex[bit_pos] = rsp->index;
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+index 8b7fc0af91ced2..532e84bc38c73c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+@@ -343,6 +343,11 @@ static void otx2_get_pauseparam(struct net_device *netdev,
+ if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
+ rsp = (struct cgx_pause_frm_cfg *)
+ otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ mutex_unlock(&pfvf->mbox.lock);
++ return;
++ }
++
+ pause->rx_pause = rsp->rx_pause;
+ pause->tx_pause = rsp->tx_pause;
+ }
+@@ -1082,6 +1087,11 @@ static int otx2_set_fecparam(struct net_device *netdev,
+
+ rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
+ 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ err = PTR_ERR(rsp);
++ goto end;
++ }
++
+ if (rsp->fec >= 0)
+ pfvf->linfo.fec = rsp->fec;
+ else
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+index 97a71e9b856372..e6082f90f57a50 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+@@ -121,6 +121,8 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count)
+
+ rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
+ (&pfvf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp))
++ goto exit;
+
+ for (ent = 0; ent < rsp->count; ent++)
+ flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent];
+@@ -199,6 +201,10 @@ static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
+
+ rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
+ (&pfvf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp)) {
++ mutex_unlock(&pfvf->mbox.lock);
++ return PTR_ERR(rsp);
++ }
+
+ if (rsp->count != req->count) {
+ netdev_info(pfvf->netdev,
+@@ -234,6 +240,10 @@ static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
+
+ frsp = (struct npc_get_field_status_rsp *)otx2_mbox_get_rsp
+ (&pfvf->mbox.mbox, 0, &freq->hdr);
++ if (IS_ERR(frsp)) {
++ mutex_unlock(&pfvf->mbox.lock);
++ return PTR_ERR(frsp);
++ }
+
+ if (frsp->enable) {
+ pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 3f46d5e0fb2ecb..b4194ec2a1f2d0 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -1150,6 +1150,23 @@ static int otx2_cgx_config_linkevents(struct otx2_nic *pf, bool enable)
+ return err;
+ }
+
++int otx2_reset_mac_stats(struct otx2_nic *pfvf)
++{
++ struct msg_req *req;
++ int err;
++
++ mutex_lock(&pfvf->mbox.lock);
++ req = otx2_mbox_alloc_msg_cgx_stats_rst(&pfvf->mbox);
++ if (!req) {
++ mutex_unlock(&pfvf->mbox.lock);
++ return -ENOMEM;
++ }
++
++ err = otx2_sync_mbox_msg(&pfvf->mbox);
++ mutex_unlock(&pfvf->mbox.lock);
++ return err;
++}
++
+ static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
+ {
+ struct msg_req *msg;
+@@ -3038,6 +3055,9 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ netdev->min_mtu = OTX2_MIN_MTU;
+ netdev->max_mtu = otx2_get_max_mtu(pf);
+
++ /* reset CGX/RPM MAC stats */
++ otx2_reset_mac_stats(pf);
++
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(dev, "Failed to register netdevice\n");
+diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
+index d5691b6a2bc54e..f2ca4376b48c6f 100644
+--- a/drivers/net/ethernet/marvell/pxa168_eth.c
++++ b/drivers/net/ethernet/marvell/pxa168_eth.c
+@@ -1394,18 +1394,15 @@ static int pxa168_eth_probe(struct platform_device *pdev)
+
+ printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
+
+- clk = devm_clk_get(&pdev->dev, NULL);
++ clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+- dev_err(&pdev->dev, "Fast Ethernet failed to get clock\n");
++ dev_err(&pdev->dev, "Fast Ethernet failed to get and enable clock\n");
+ return -ENODEV;
+ }
+- clk_prepare_enable(clk);
+
+ dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
+- if (!dev) {
+- err = -ENOMEM;
+- goto err_clk;
+- }
++ if (!dev)
++ return -ENOMEM;
+
+ platform_set_drvdata(pdev, dev);
+ pep = netdev_priv(dev);
+@@ -1523,8 +1520,6 @@ static int pxa168_eth_probe(struct platform_device *pdev)
+ mdiobus_free(pep->smi_bus);
+ err_netdev:
+ free_netdev(dev);
+-err_clk:
+- clk_disable_unprepare(clk);
+ return err;
+ }
+
+@@ -1542,7 +1537,6 @@ static int pxa168_eth_remove(struct platform_device *pdev)
+ if (dev->phydev)
+ phy_disconnect(dev->phydev);
+
+- clk_disable_unprepare(pep->clk);
+ mdiobus_unregister(pep->smi_bus);
+ mdiobus_free(pep->smi_bus);
+ unregister_netdev(dev);
+diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c
+index 66ef14d95bf6f7..88744ae6529354 100644
+--- a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c
++++ b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c
+@@ -366,12 +366,13 @@ static void vcap_api_iterator_init_test(struct kunit *test)
+ struct vcap_typegroup typegroups[] = {
+ { .offset = 0, .width = 2, .value = 2, },
+ { .offset = 156, .width = 1, .value = 0, },
+- { .offset = 0, .width = 0, .value = 0, },
++ { }
+ };
+ struct vcap_typegroup typegroups2[] = {
+ { .offset = 0, .width = 3, .value = 4, },
+ { .offset = 49, .width = 2, .value = 0, },
+ { .offset = 98, .width = 2, .value = 0, },
++ { }
+ };
+
+ vcap_iter_init(&iter, 52, typegroups, 86);
+@@ -399,6 +400,7 @@ static void vcap_api_iterator_next_test(struct kunit *test)
+ { .offset = 147, .width = 3, .value = 0, },
+ { .offset = 196, .width = 2, .value = 0, },
+ { .offset = 245, .width = 1, .value = 0, },
++ { }
+ };
+ int idx;
+
+@@ -433,7 +435,7 @@ static void vcap_api_encode_typegroups_test(struct kunit *test)
+ { .offset = 147, .width = 3, .value = 5, },
+ { .offset = 196, .width = 2, .value = 2, },
+ { .offset = 245, .width = 5, .value = 27, },
+- { .offset = 0, .width = 0, .value = 0, },
++ { }
+ };
+
+ vcap_encode_typegroups(stream, 49, typegroups, false);
+@@ -463,6 +465,7 @@ static void vcap_api_encode_bit_test(struct kunit *test)
+ { .offset = 147, .width = 3, .value = 5, },
+ { .offset = 196, .width = 2, .value = 2, },
+ { .offset = 245, .width = 1, .value = 0, },
++ { }
+ };
+
+ vcap_iter_init(&iter, 49, typegroups, 44);
+@@ -489,7 +492,7 @@ static void vcap_api_encode_field_test(struct kunit *test)
+ { .offset = 147, .width = 3, .value = 5, },
+ { .offset = 196, .width = 2, .value = 2, },
+ { .offset = 245, .width = 5, .value = 27, },
+- { .offset = 0, .width = 0, .value = 0, },
++ { }
+ };
+ struct vcap_field rf = {
+ .type = VCAP_FIELD_U32,
+@@ -538,7 +541,7 @@ static void vcap_api_encode_short_field_test(struct kunit *test)
+ { .offset = 0, .width = 3, .value = 7, },
+ { .offset = 21, .width = 2, .value = 3, },
+ { .offset = 42, .width = 1, .value = 1, },
+- { .offset = 0, .width = 0, .value = 0, },
++ { }
+ };
+ struct vcap_field rf = {
+ .type = VCAP_FIELD_U32,
+@@ -608,7 +611,7 @@ static void vcap_api_encode_keyfield_test(struct kunit *test)
+ struct vcap_typegroup tgt[] = {
+ { .offset = 0, .width = 2, .value = 2, },
+ { .offset = 156, .width = 1, .value = 1, },
+- { .offset = 0, .width = 0, .value = 0, },
++ { }
+ };
+
+ vcap_test_api_init(&admin);
+@@ -671,7 +674,7 @@ static void vcap_api_encode_max_keyfield_test(struct kunit *test)
+ struct vcap_typegroup tgt[] = {
+ { .offset = 0, .width = 2, .value = 2, },
+ { .offset = 156, .width = 1, .value = 1, },
+- { .offset = 0, .width = 0, .value = 0, },
++ { }
+ };
+ u32 keyres[] = {
+ 0x928e8a84,
+@@ -732,7 +735,7 @@ static void vcap_api_encode_actionfield_test(struct kunit *test)
+ { .offset = 0, .width = 2, .value = 2, },
+ { .offset = 21, .width = 1, .value = 1, },
+ { .offset = 42, .width = 1, .value = 0, },
+- { .offset = 0, .width = 0, .value = 0, },
++ { }
+ };
+
+ vcap_encode_actionfield(&rule, &caf, &rf, tgt);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+index 9bf102bbc6a004..5d20325a18dd3d 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+@@ -429,6 +429,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
+ plat_dat->bsp_priv = dwmac;
+ plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
+
++ plat_dat->riwt_off = 1;
++
+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ if (ret)
+ goto err_remove_config_dt;
+diff --git a/drivers/net/mdio/mdio-ipq4019.c b/drivers/net/mdio/mdio-ipq4019.c
+index 78b93de636f57f..0e13fca8731ab3 100644
+--- a/drivers/net/mdio/mdio-ipq4019.c
++++ b/drivers/net/mdio/mdio-ipq4019.c
+@@ -255,8 +255,11 @@ static int ipq4019_mdio_probe(struct platform_device *pdev)
+ /* The platform resource is provided on the chipset IPQ5018 */
+ /* This resource is optional */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+- if (res)
++ if (res) {
+ priv->eth_ldo_rdy = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(priv->eth_ldo_rdy))
++ return PTR_ERR(priv->eth_ldo_rdy);
++ }
+
+ bus->name = "ipq4019_mdio";
+ bus->read = ipq4019_mdio_read_c22;
+diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c
+index f0d58092e7e961..3612b0633bd177 100644
+--- a/drivers/net/netdevsim/ipsec.c
++++ b/drivers/net/netdevsim/ipsec.c
+@@ -176,14 +176,13 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs,
+ return ret;
+ }
+
+- if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
++ if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN)
+ sa.rx = true;
+
+- if (xs->props.family == AF_INET6)
+- memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
+- else
+- memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
+- }
++ if (xs->props.family == AF_INET6)
++ memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
++ else
++ memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
+
+ /* the preparations worked, so save the info */
+ memcpy(&ipsec->sa[sa_idx], &sa, sizeof(sa));
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 921ae046f86041..09173d7b87ed5c 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -1657,13 +1657,13 @@ static int lan78xx_set_wol(struct net_device *netdev,
+ struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
+ int ret;
+
++ if (wol->wolopts & ~WAKE_ALL)
++ return -EINVAL;
++
+ ret = usb_autopm_get_interface(dev->intf);
+ if (ret < 0)
+ return ret;
+
+- if (wol->wolopts & ~WAKE_ALL)
+- return -EINVAL;
+-
+ pdata->wol = wol->wolopts;
+
+ device_set_wakeup_enable(&dev->udev->dev, (bool)wol->wolopts);
+@@ -2387,6 +2387,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
+ if (dev->chipid == ID_REV_CHIP_ID_7801_) {
+ if (phy_is_pseudo_fixed_link(phydev)) {
+ fixed_phy_unregister(phydev);
++ phy_device_free(phydev);
+ } else {
+ phy_unregister_fixup_for_uid(PHY_KSZ9031RNX,
+ 0xfffffff0);
+@@ -4246,8 +4247,10 @@ static void lan78xx_disconnect(struct usb_interface *intf)
+
+ phy_disconnect(net->phydev);
+
+- if (phy_is_pseudo_fixed_link(phydev))
++ if (phy_is_pseudo_fixed_link(phydev)) {
+ fixed_phy_unregister(phydev);
++ phy_device_free(phydev);
++ }
+
+ usb_scuttle_anchored_urbs(&dev->deferred);
+
+@@ -4414,29 +4417,30 @@ static int lan78xx_probe(struct usb_interface *intf,
+
+ period = ep_intr->desc.bInterval;
+ maxp = usb_maxpacket(dev->udev, dev->pipe_intr);
+- buf = kmalloc(maxp, GFP_KERNEL);
+- if (!buf) {
++
++ dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
++ if (!dev->urb_intr) {
+ ret = -ENOMEM;
+ goto out5;
+ }
+
+- dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
+- if (!dev->urb_intr) {
++ buf = kmalloc(maxp, GFP_KERNEL);
++ if (!buf) {
+ ret = -ENOMEM;
+- goto out6;
+- } else {
+- usb_fill_int_urb(dev->urb_intr, dev->udev,
+- dev->pipe_intr, buf, maxp,
+- intr_complete, dev, period);
+- dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
++ goto free_urbs;
+ }
+
++ usb_fill_int_urb(dev->urb_intr, dev->udev,
++ dev->pipe_intr, buf, maxp,
++ intr_complete, dev, period);
++ dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
++
+ dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out);
+
+ /* Reject broken descriptors. */
+ if (dev->maxpacket == 0) {
+ ret = -ENODEV;
+- goto out6;
++ goto free_urbs;
+ }
+
+ /* driver requires remote-wakeup capability during autosuspend. */
+@@ -4444,7 +4448,7 @@ static int lan78xx_probe(struct usb_interface *intf,
+
+ ret = lan78xx_phy_init(dev);
+ if (ret < 0)
+- goto out7;
++ goto free_urbs;
+
+ ret = register_netdev(netdev);
+ if (ret != 0) {
+@@ -4466,10 +4470,8 @@ static int lan78xx_probe(struct usb_interface *intf,
+
+ out8:
+ phy_disconnect(netdev->phydev);
+-out7:
++free_urbs:
+ usb_free_urb(dev->urb_intr);
+-out6:
+- kfree(buf);
+ out5:
+ lan78xx_unbind(dev, intf);
+ out4:
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 2cf4324a12fd18..89775b6d0699a0 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1084,6 +1084,7 @@ static const struct usb_device_id products[] = {
+ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
+ .driver_info = (unsigned long)&qmi_wwan_info,
+ },
++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */
+ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */
+ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */
+ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index ce19ebd180f126..3e5998555f9814 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -10016,6 +10016,7 @@ static const struct usb_device_id rtl8152_table[] = {
+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3062) },
+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3069) },
+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3082) },
++ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3098) },
+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x7205) },
+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x720c) },
+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x7214) },
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 03e7bc5b6c0bd0..d5e6e11f630b95 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -9119,7 +9119,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss1[
+ {6, {2633, 2925}, {1215, 1350}, {585, 650} },
+ {7, {2925, 3250}, {1350, 1500}, {650, 722} },
+ {8, {3510, 3900}, {1620, 1800}, {780, 867} },
+- {9, {3900, 4333}, {1800, 2000}, {780, 867} }
++ {9, {3900, 4333}, {1800, 2000}, {865, 960} }
+ };
+
+ /*MCS parameters with Nss = 2 */
+@@ -9134,7 +9134,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss2[
+ {6, {5265, 5850}, {2430, 2700}, {1170, 1300} },
+ {7, {5850, 6500}, {2700, 3000}, {1300, 1444} },
+ {8, {7020, 7800}, {3240, 3600}, {1560, 1733} },
+- {9, {7800, 8667}, {3600, 4000}, {1560, 1733} }
++ {9, {7800, 8667}, {3600, 4000}, {1730, 1920} }
+ };
+
+ static void ath10k_mac_get_rate_flags_ht(struct ath10k *ar, u32 rate, u8 nss, u8 mcs,
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
+index 83dc284392de22..fa46e645009cf6 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -2180,6 +2180,9 @@ static int ath11k_qmi_request_device_info(struct ath11k_base *ab)
+ ab->mem = bar_addr_va;
+ ab->mem_len = resp.bar_size;
+
++ if (!ab->hw_params.ce_remap)
++ ab->mem_ce = ab->mem;
++
+ return 0;
+ out:
+ return ret;
+diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
+index 907655c45a4b9a..c663ff990b4791 100644
+--- a/drivers/net/wireless/ath/ath12k/dp.c
++++ b/drivers/net/wireless/ath/ath12k/dp.c
+@@ -1214,6 +1214,7 @@ static void ath12k_dp_cc_cleanup(struct ath12k_base *ab)
+ }
+
+ kfree(dp->spt_info);
++ dp->spt_info = NULL;
+ }
+
+ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
+@@ -1249,8 +1250,10 @@ void ath12k_dp_free(struct ath12k_base *ab)
+
+ ath12k_dp_rx_reo_cmd_list_cleanup(ab);
+
+- for (i = 0; i < ab->hw_params->max_tx_ring; i++)
++ for (i = 0; i < ab->hw_params->max_tx_ring; i++) {
+ kfree(dp->tx_ring[i].tx_status);
++ dp->tx_ring[i].tx_status = NULL;
++ }
+
+ ath12k_dp_rx_free(ab);
+ /* Deinit any SOC level resource */
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index 4bb30e40372877..f90191a290c26a 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -775,7 +775,10 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar)
+
+ spin_lock_bh(&ab->base_lock);
+ list_for_each_entry_safe(peer, tmp, &ab->peers, list) {
+- ath12k_dp_rx_peer_tid_cleanup(ar, peer);
++ /* Skip Rx TID cleanup for self peer */
++ if (peer->sta)
++ ath12k_dp_rx_peer_tid_cleanup(ar, peer);
++
+ list_del(&peer->list);
+ kfree(peer);
+ }
+diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
+index 99667aba289df0..00dc97ac53b9d8 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
+@@ -294,6 +294,9 @@ int htc_connect_service(struct htc_target *target,
+ return -ETIMEDOUT;
+ }
+
++ if (target->conn_rsp_epid < 0 || target->conn_rsp_epid >= ENDPOINT_MAX)
++ return -EINVAL;
++
+ *conn_rsp_epid = target->conn_rsp_epid;
+ return 0;
+ err:
+diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
+index f29ac6de713994..19702b6f09c329 100644
+--- a/drivers/net/wireless/ath/wil6210/txrx.c
++++ b/drivers/net/wireless/ath/wil6210/txrx.c
+@@ -306,7 +306,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
+ struct sk_buff *skb)
+ {
+ struct wil6210_rtap {
+- struct ieee80211_radiotap_header rthdr;
++ struct ieee80211_radiotap_header_fixed rthdr;
+ /* fields should be in the order of bits in rthdr.it_present */
+ /* flags */
+ u8 flags;
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+index e406e11481a621..73fc701204e29b 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+@@ -109,9 +109,8 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
+ }
+ strreplace(board_type, '/', '-');
+ settings->board_type = board_type;
+-
+- of_node_put(root);
+ }
++ of_node_put(root);
+
+ if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
+ return;
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index 0812db8936f132..9e9ff0cb724cac 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -2520,7 +2520,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
+ * to build this manually element by element, we can write it much
+ * more efficiently than we can parse it. ORDER MATTERS HERE */
+ struct ipw_rt_hdr {
+- struct ieee80211_radiotap_header rt_hdr;
++ struct ieee80211_radiotap_header_fixed rt_hdr;
+ s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
+ } *ipw_rt;
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.h b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
+index 8ebf09121e173c..226286cb7eb822 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.h
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.h
+@@ -1143,7 +1143,7 @@ struct ipw_prom_priv {
+ * structure is provided regardless of any bits unset.
+ */
+ struct ipw_rt_hdr {
+- struct ieee80211_radiotap_header rt_hdr;
++ struct ieee80211_radiotap_header_fixed rt_hdr;
+ u64 rt_tsf; /* TSF */ /* XXX */
+ u8 rt_flags; /* radiotap packet flags */
+ u8 rt_rate; /* rate in 500kb/s */
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c
+index 135bd48bfe9fa8..cf02a2afbee56f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/init.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c
+@@ -39,10 +39,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
+ }
+ IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
+
++/* Assumes the appropriate lock is held by the caller */
+ void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)
+ {
+ iwl_fw_suspend_timestamp(fwrt);
+- iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, NULL);
++ iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START,
++ NULL);
+ }
+ IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+index 08d1fab7f53c3a..592b9157d50c67 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+@@ -1382,7 +1382,9 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+
+ iwl_mvm_pause_tcm(mvm, true);
+
++ mutex_lock(&mvm->mutex);
+ iwl_fw_runtime_suspend(&mvm->fwrt);
++ mutex_unlock(&mvm->mutex);
+
+ return __iwl_mvm_suspend(hw, wowlan, false);
+ }
+diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c
+index ce0179b8ab368f..90ebed33d792ba 100644
+--- a/drivers/net/wireless/intersil/p54/p54spi.c
++++ b/drivers/net/wireless/intersil/p54/p54spi.c
+@@ -624,7 +624,7 @@ static int p54spi_probe(struct spi_device *spi)
+ gpio_direction_input(p54spi_gpio_irq);
+
+ ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
+- p54spi_interrupt, 0, "p54spi",
++ p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi",
+ priv->spi);
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "request_irq() failed");
+@@ -633,8 +633,6 @@ static int p54spi_probe(struct spi_device *spi)
+
+ irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
+
+- disable_irq(gpio_to_irq(p54spi_gpio_irq));
+-
+ INIT_WORK(&priv->work, p54spi_work);
+ init_completion(&priv->fw_comp);
+ INIT_LIST_HEAD(&priv->tx_pending);
+diff --git a/drivers/net/wireless/marvell/libertas/radiotap.h b/drivers/net/wireless/marvell/libertas/radiotap.h
+index 1ed5608d353ff5..d543bfe739dcb9 100644
+--- a/drivers/net/wireless/marvell/libertas/radiotap.h
++++ b/drivers/net/wireless/marvell/libertas/radiotap.h
+@@ -2,7 +2,7 @@
+ #include <net/ieee80211_radiotap.h>
+
+ struct tx_radiotap_hdr {
+- struct ieee80211_radiotap_header hdr;
++ struct ieee80211_radiotap_header_fixed hdr;
+ u8 rate;
+ u8 txpower;
+ u8 rts_retries;
+@@ -31,7 +31,7 @@ struct tx_radiotap_hdr {
+ #define IEEE80211_FC_DSTODS 0x0300
+
+ struct rx_radiotap_hdr {
+- struct ieee80211_radiotap_header hdr;
++ struct ieee80211_radiotap_header_fixed hdr;
+ u8 flags;
+ u8 rate;
+ u8 antsignal;
+diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
+index a3be37526697b4..7b06a6d57ffb0b 100644
+--- a/drivers/net/wireless/marvell/mwifiex/fw.h
++++ b/drivers/net/wireless/marvell/mwifiex/fw.h
+@@ -842,7 +842,7 @@ struct mwifiex_ietypes_chanstats {
+ struct mwifiex_ie_types_wildcard_ssid_params {
+ struct mwifiex_ie_types_header header;
+ u8 max_ssid_length;
+- u8 ssid[1];
++ u8 ssid[];
+ } __packed;
+
+ #define TSF_DATA_SIZE 8
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
+index d99127dc466ecb..6c60a4c21a3128 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1633,7 +1633,8 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
+ }
+
+ ret = devm_request_irq(dev, adapter->irq_wakeup,
+- mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
++ mwifiex_irq_wakeup_handler,
++ IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
+ "wifi_wake", adapter);
+ if (ret) {
+ dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
+@@ -1641,7 +1642,6 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
+ goto err_exit;
+ }
+
+- disable_irq(adapter->irq_wakeup);
+ if (device_init_wakeup(dev, true)) {
+ dev_err(dev, "fail to init wakeup for mwifiex\n");
+ goto err_exit;
+diff --git a/drivers/net/wireless/microchip/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c
+index 03b7229a0ff5aa..c3d27aaec29742 100644
+--- a/drivers/net/wireless/microchip/wilc1000/mon.c
++++ b/drivers/net/wireless/microchip/wilc1000/mon.c
+@@ -7,12 +7,12 @@
+ #include "cfg80211.h"
+
+ struct wilc_wfi_radiotap_hdr {
+- struct ieee80211_radiotap_header hdr;
++ struct ieee80211_radiotap_header_fixed hdr;
+ u8 rate;
+ } __packed;
+
+ struct wilc_wfi_radiotap_cb_hdr {
+- struct ieee80211_radiotap_header hdr;
++ struct ieee80211_radiotap_header_fixed hdr;
+ u8 rate;
+ u8 dump;
+ u16 tx_flags;
+diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c
+index 2e945554ed6d59..6c8efd2b264269 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/efuse.c
++++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c
+@@ -162,10 +162,19 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
+ void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+ {
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
++ u16 max_attempts = 10000;
+ u32 value32;
+ u8 readbyte;
+ u16 retry;
+
++ /*
++ * In case of USB devices, transfer speeds are limited, hence
++ * efuse I/O reads could be (way) slower. So, decrease (a lot)
++ * the read attempts in case of failures.
++ */
++ if (rtlpriv->rtlhal.interface == INTF_USB)
++ max_attempts = 10;
++
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+ (_offset & 0xff));
+ readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+@@ -178,7 +187,7 @@ void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+
+ retry = 0;
+ value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+- while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
++ while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < max_attempts)) {
+ value32 = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[EFUSE_CTRL]);
+ retry++;
+diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c
+index ede822d771aafb..f2409830d87e30 100644
+--- a/drivers/net/wireless/silabs/wfx/main.c
++++ b/drivers/net/wireless/silabs/wfx/main.c
+@@ -475,10 +475,23 @@ static int __init wfx_core_init(void)
+ {
+ int ret = 0;
+
+- if (IS_ENABLED(CONFIG_SPI))
++ if (IS_ENABLED(CONFIG_SPI)) {
+ ret = spi_register_driver(&wfx_spi_driver);
+- if (IS_ENABLED(CONFIG_MMC) && !ret)
++ if (ret)
++ goto out;
++ }
++ if (IS_ENABLED(CONFIG_MMC)) {
+ ret = sdio_register_driver(&wfx_sdio_driver);
++ if (ret)
++ goto unregister_spi;
++ }
++
++ return 0;
++
++unregister_spi:
++ if (IS_ENABLED(CONFIG_SPI))
++ spi_unregister_driver(&wfx_spi_driver);
++out:
+ return ret;
+ }
+ module_init(wfx_core_init);
+diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
+index 07be0adc13ec5c..d86a1bd7aab089 100644
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -736,7 +736,7 @@ static const struct rhashtable_params hwsim_rht_params = {
+ };
+
+ struct hwsim_radiotap_hdr {
+- struct ieee80211_radiotap_header hdr;
++ struct ieee80211_radiotap_header_fixed hdr;
+ __le64 rt_tsft;
+ u8 rt_flags;
+ u8 rt_rate;
+@@ -745,7 +745,7 @@ struct hwsim_radiotap_hdr {
+ } __packed;
+
+ struct hwsim_radiotap_ack_hdr {
+- struct ieee80211_radiotap_header hdr;
++ struct ieee80211_radiotap_header_fixed hdr;
+ u8 rt_flags;
+ u8 pad;
+ __le16 rt_channel;
+diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
+index 596bb11eeba5a9..396eb943765979 100644
+--- a/drivers/nvme/host/apple.c
++++ b/drivers/nvme/host/apple.c
+@@ -1387,7 +1387,7 @@ static void devm_apple_nvme_mempool_destroy(void *data)
+ mempool_destroy(data);
+ }
+
+-static int apple_nvme_probe(struct platform_device *pdev)
++static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+ struct apple_nvme *anv;
+@@ -1395,7 +1395,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
+
+ anv = devm_kzalloc(dev, sizeof(*anv), GFP_KERNEL);
+ if (!anv)
+- return -ENOMEM;
++ return ERR_PTR(-ENOMEM);
+
+ anv->dev = get_device(dev);
+ anv->adminq.is_adminq = true;
+@@ -1515,10 +1515,26 @@ static int apple_nvme_probe(struct platform_device *pdev)
+ goto put_dev;
+ }
+
++ return anv;
++put_dev:
++ put_device(anv->dev);
++ return ERR_PTR(ret);
++}
++
++static int apple_nvme_probe(struct platform_device *pdev)
++{
++ struct apple_nvme *anv;
++ int ret;
++
++ anv = apple_nvme_alloc(pdev);
++ if (IS_ERR(anv))
++ return PTR_ERR(anv);
++
+ anv->ctrl.admin_q = blk_mq_init_queue(&anv->admin_tagset);
+ if (IS_ERR(anv->ctrl.admin_q)) {
+ ret = -ENOMEM;
+- goto put_dev;
++ anv->ctrl.admin_q = NULL;
++ goto out_uninit_ctrl;
+ }
+
+ nvme_reset_ctrl(&anv->ctrl);
+@@ -1526,8 +1542,9 @@ static int apple_nvme_probe(struct platform_device *pdev)
+
+ return 0;
+
+-put_dev:
+- put_device(anv->dev);
++out_uninit_ctrl:
++ nvme_uninit_ctrl(&anv->ctrl);
++ nvme_put_ctrl(&anv->ctrl);
+ return ret;
+ }
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 965ca7d7a3de22..5b6a6bd4e6e800 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -109,7 +109,7 @@ struct workqueue_struct *nvme_delete_wq;
+ EXPORT_SYMBOL_GPL(nvme_delete_wq);
+
+ static LIST_HEAD(nvme_subsystems);
+-static DEFINE_MUTEX(nvme_subsystems_lock);
++DEFINE_MUTEX(nvme_subsystems_lock);
+
+ static DEFINE_IDA(nvme_instance_ida);
+ static dev_t nvme_ctrl_base_chr_devt;
+diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
+index 875dee6ecd4081..19a7f0160618d1 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -3,6 +3,7 @@
+ * Copyright (c) 2011-2014, Intel Corporation.
+ * Copyright (c) 2017-2021 Christoph Hellwig.
+ */
++#include <linux/blk-integrity.h>
+ #include <linux/ptrace.h> /* for force_successful_syscall_return */
+ #include <linux/nvme_ioctl.h>
+ #include <linux/io_uring.h>
+@@ -171,10 +172,15 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
+ struct request_queue *q = req->q;
+ struct nvme_ns *ns = q->queuedata;
+ struct block_device *bdev = ns ? ns->disk->part0 : NULL;
++ bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk);
++ bool has_metadata = meta_buffer && meta_len;
+ struct bio *bio = NULL;
+ void *meta = NULL;
+ int ret;
+
++ if (has_metadata && !supports_metadata)
++ return -EINVAL;
++
+ if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
+ struct iov_iter iter;
+
+@@ -198,7 +204,7 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
+ if (bdev)
+ bio_set_dev(bio, bdev);
+
+- if (bdev && meta_buffer && meta_len) {
++ if (has_metadata) {
+ meta = nvme_add_user_metadata(req, meta_buffer, meta_len,
+ meta_seed);
+ if (IS_ERR(meta)) {
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index ede2a14dad8be7..32283301199f01 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -17,6 +17,7 @@ MODULE_PARM_DESC(multipath,
+ static const char *nvme_iopolicy_names[] = {
+ [NVME_IOPOLICY_NUMA] = "numa",
+ [NVME_IOPOLICY_RR] = "round-robin",
++ [NVME_IOPOLICY_QD] = "queue-depth",
+ };
+
+ static int iopolicy = NVME_IOPOLICY_NUMA;
+@@ -29,6 +30,8 @@ static int nvme_set_iopolicy(const char *val, const struct kernel_param *kp)
+ iopolicy = NVME_IOPOLICY_NUMA;
+ else if (!strncmp(val, "round-robin", 11))
+ iopolicy = NVME_IOPOLICY_RR;
++ else if (!strncmp(val, "queue-depth", 11))
++ iopolicy = NVME_IOPOLICY_QD;
+ else
+ return -EINVAL;
+
+@@ -43,7 +46,7 @@ static int nvme_get_iopolicy(char *buf, const struct kernel_param *kp)
+ module_param_call(iopolicy, nvme_set_iopolicy, nvme_get_iopolicy,
+ &iopolicy, 0644);
+ MODULE_PARM_DESC(iopolicy,
+- "Default multipath I/O policy; 'numa' (default) or 'round-robin'");
++ "Default multipath I/O policy; 'numa' (default), 'round-robin' or 'queue-depth'");
+
+ void nvme_mpath_default_iopolicy(struct nvme_subsystem *subsys)
+ {
+@@ -128,6 +131,11 @@ void nvme_mpath_start_request(struct request *rq)
+ struct nvme_ns *ns = rq->q->queuedata;
+ struct gendisk *disk = ns->head->disk;
+
++ if (READ_ONCE(ns->head->subsys->iopolicy) == NVME_IOPOLICY_QD) {
++ atomic_inc(&ns->ctrl->nr_active);
++ nvme_req(rq)->flags |= NVME_MPATH_CNT_ACTIVE;
++ }
++
+ if (!blk_queue_io_stat(disk->queue) || blk_rq_is_passthrough(rq))
+ return;
+
+@@ -141,6 +149,9 @@ void nvme_mpath_end_request(struct request *rq)
+ {
+ struct nvme_ns *ns = rq->q->queuedata;
+
++ if (nvme_req(rq)->flags & NVME_MPATH_CNT_ACTIVE)
++ atomic_dec_if_positive(&ns->ctrl->nr_active);
++
+ if (!(nvme_req(rq)->flags & NVME_MPATH_IO_STATS))
+ return;
+ bdev_end_io_acct(ns->head->disk->part0, req_op(rq),
+@@ -154,7 +165,8 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl)
+ int srcu_idx;
+
+ srcu_idx = srcu_read_lock(&ctrl->srcu);
+- list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
++ list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
++ srcu_read_lock_held(&ctrl->srcu)) {
+ if (!ns->head->disk)
+ continue;
+ kblockd_schedule_work(&ns->head->requeue_work);
+@@ -198,7 +210,8 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
+ int srcu_idx;
+
+ srcu_idx = srcu_read_lock(&ctrl->srcu);
+- list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
++ list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
++ srcu_read_lock_held(&ctrl->srcu)) {
+ nvme_mpath_clear_current_path(ns);
+ kblockd_schedule_work(&ns->head->requeue_work);
+ }
+@@ -213,7 +226,8 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
+ int srcu_idx;
+
+ srcu_idx = srcu_read_lock(&head->srcu);
+- list_for_each_entry_rcu(ns, &head->list, siblings) {
++ list_for_each_entry_srcu(ns, &head->list, siblings,
++ srcu_read_lock_held(&head->srcu)) {
+ if (capacity != get_capacity(ns->disk))
+ clear_bit(NVME_NS_READY, &ns->flags);
+ }
+@@ -245,7 +259,8 @@ static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node)
+ int found_distance = INT_MAX, fallback_distance = INT_MAX, distance;
+ struct nvme_ns *found = NULL, *fallback = NULL, *ns;
+
+- list_for_each_entry_rcu(ns, &head->list, siblings) {
++ list_for_each_entry_srcu(ns, &head->list, siblings,
++ srcu_read_lock_held(&head->srcu)) {
+ if (nvme_path_is_disabled(ns))
+ continue;
+
+@@ -290,10 +305,15 @@ static struct nvme_ns *nvme_next_ns(struct nvme_ns_head *head,
+ return list_first_or_null_rcu(&head->list, struct nvme_ns, siblings);
+ }
+
+-static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head,
+- int node, struct nvme_ns *old)
++static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head)
+ {
+ struct nvme_ns *ns, *found = NULL;
++ int node = numa_node_id();
++ struct nvme_ns *old = srcu_dereference(head->current_path[node],
++ &head->srcu);
++
++ if (unlikely(!old))
++ return __nvme_find_path(head, node);
+
+ if (list_is_singular(&head->list)) {
+ if (nvme_path_is_disabled(old))
+@@ -333,13 +353,50 @@ static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head,
+ return found;
+ }
+
++static struct nvme_ns *nvme_queue_depth_path(struct nvme_ns_head *head)
++{
++ struct nvme_ns *best_opt = NULL, *best_nonopt = NULL, *ns;
++ unsigned int min_depth_opt = UINT_MAX, min_depth_nonopt = UINT_MAX;
++ unsigned int depth;
++
++ list_for_each_entry_srcu(ns, &head->list, siblings,
++ srcu_read_lock_held(&head->srcu)) {
++ if (nvme_path_is_disabled(ns))
++ continue;
++
++ depth = atomic_read(&ns->ctrl->nr_active);
++
++ switch (ns->ana_state) {
++ case NVME_ANA_OPTIMIZED:
++ if (depth < min_depth_opt) {
++ min_depth_opt = depth;
++ best_opt = ns;
++ }
++ break;
++ case NVME_ANA_NONOPTIMIZED:
++ if (depth < min_depth_nonopt) {
++ min_depth_nonopt = depth;
++ best_nonopt = ns;
++ }
++ break;
++ default:
++ break;
++ }
++
++ if (min_depth_opt == 0)
++ return best_opt;
++ }
++
++ return best_opt ? best_opt : best_nonopt;
++}
++
+ static inline bool nvme_path_is_optimized(struct nvme_ns *ns)
+ {
+ return ns->ctrl->state == NVME_CTRL_LIVE &&
+ ns->ana_state == NVME_ANA_OPTIMIZED;
+ }
+
+-inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head)
++static struct nvme_ns *nvme_numa_path(struct nvme_ns_head *head)
+ {
+ int node = numa_node_id();
+ struct nvme_ns *ns;
+@@ -347,19 +404,32 @@ inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head)
+ ns = srcu_dereference(head->current_path[node], &head->srcu);
+ if (unlikely(!ns))
+ return __nvme_find_path(head, node);
+-
+- if (READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_RR)
+- return nvme_round_robin_path(head, node, ns);
+ if (unlikely(!nvme_path_is_optimized(ns)))
+ return __nvme_find_path(head, node);
+ return ns;
+ }
+
++inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head)
++{
++ switch (READ_ONCE(head->subsys->iopolicy)) {
++ case NVME_IOPOLICY_QD:
++ return nvme_queue_depth_path(head);
++ case NVME_IOPOLICY_RR:
++ return nvme_round_robin_path(head);
++ default:
++ return nvme_numa_path(head);
++ }
++}
++
+ static bool nvme_available_path(struct nvme_ns_head *head)
+ {
+ struct nvme_ns *ns;
+
+- list_for_each_entry_rcu(ns, &head->list, siblings) {
++ if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags))
++ return NULL;
++
++ list_for_each_entry_srcu(ns, &head->list, siblings,
++ srcu_read_lock_held(&head->srcu)) {
+ if (test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ns->ctrl->flags))
+ continue;
+ switch (ns->ctrl->state) {
+@@ -720,7 +790,8 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
+ return 0;
+
+ srcu_idx = srcu_read_lock(&ctrl->srcu);
+- list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
++ list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
++ srcu_read_lock_held(&ctrl->srcu)) {
+ unsigned nsid;
+ again:
+ nsid = le32_to_cpu(desc->nsids[n]);
+@@ -827,6 +898,29 @@ static ssize_t nvme_subsys_iopolicy_show(struct device *dev,
+ nvme_iopolicy_names[READ_ONCE(subsys->iopolicy)]);
+ }
+
++static void nvme_subsys_iopolicy_update(struct nvme_subsystem *subsys,
++ int iopolicy)
++{
++ struct nvme_ctrl *ctrl;
++ int old_iopolicy = READ_ONCE(subsys->iopolicy);
++
++ if (old_iopolicy == iopolicy)
++ return;
++
++ WRITE_ONCE(subsys->iopolicy, iopolicy);
++
++ /* iopolicy changes clear the mpath by design */
++ mutex_lock(&nvme_subsystems_lock);
++ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
++ nvme_mpath_clear_ctrl_paths(ctrl);
++ mutex_unlock(&nvme_subsystems_lock);
++
++ pr_notice("subsysnqn %s iopolicy changed from %s to %s\n",
++ subsys->subnqn,
++ nvme_iopolicy_names[old_iopolicy],
++ nvme_iopolicy_names[iopolicy]);
++}
++
+ static ssize_t nvme_subsys_iopolicy_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+ {
+@@ -836,7 +930,7 @@ static ssize_t nvme_subsys_iopolicy_store(struct device *dev,
+
+ for (i = 0; i < ARRAY_SIZE(nvme_iopolicy_names); i++) {
+ if (sysfs_streq(buf, nvme_iopolicy_names[i])) {
+- WRITE_ONCE(subsys->iopolicy, i);
++ nvme_subsys_iopolicy_update(subsys, i);
+ return count;
+ }
+ }
+@@ -912,8 +1006,7 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)
+ {
+ if (!head->disk)
+ return;
+- kblockd_schedule_work(&head->requeue_work);
+- if (test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) {
++ if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) {
+ nvme_cdev_del(&head->cdev, &head->cdev_device);
+ /*
+ * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared
+@@ -923,6 +1016,12 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)
+ kblockd_schedule_work(&head->requeue_work);
+ del_gendisk(head->disk);
+ }
++ /*
++ * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared
++ * to allow multipath to fail all I/O.
++ */
++ synchronize_srcu(&head->srcu);
++ kblockd_schedule_work(&head->requeue_work);
+ }
+
+ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
+@@ -954,6 +1053,9 @@ int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+ !(ctrl->subsys->cmic & NVME_CTRL_CMIC_ANA))
+ return 0;
+
++ /* initialize this in the identify path to cover controller resets */
++ atomic_set(&ctrl->nr_active, 0);
++
+ if (!ctrl->max_namespaces ||
+ ctrl->max_namespaces > le32_to_cpu(id->nn)) {
+ dev_err(ctrl->device,
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index 14a867245c29f3..bddc068d58c7ea 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -48,6 +48,7 @@ extern unsigned int admin_timeout;
+ extern struct workqueue_struct *nvme_wq;
+ extern struct workqueue_struct *nvme_reset_wq;
+ extern struct workqueue_struct *nvme_delete_wq;
++extern struct mutex nvme_subsystems_lock;
+
+ /*
+ * List of workarounds for devices that required behavior not specified in
+@@ -199,6 +200,7 @@ enum {
+ NVME_REQ_CANCELLED = (1 << 0),
+ NVME_REQ_USERCMD = (1 << 1),
+ NVME_MPATH_IO_STATS = (1 << 2),
++ NVME_MPATH_CNT_ACTIVE = (1 << 3),
+ };
+
+ static inline struct nvme_request *nvme_req(struct request *req)
+@@ -364,6 +366,7 @@ struct nvme_ctrl {
+ size_t ana_log_size;
+ struct timer_list anatt_timer;
+ struct work_struct ana_work;
++ atomic_t nr_active;
+ #endif
+
+ #ifdef CONFIG_NVME_AUTH
+@@ -411,6 +414,7 @@ static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl)
+ enum nvme_iopolicy {
+ NVME_IOPOLICY_NUMA,
+ NVME_IOPOLICY_RR,
++ NVME_IOPOLICY_QD,
+ };
+
+ struct nvme_subsystem {
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index b701969cf1c2aa..d525fa1229d791 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -153,6 +153,7 @@ struct nvme_dev {
+ /* host memory buffer support: */
+ u64 host_mem_size;
+ u32 nr_host_mem_descs;
++ u32 host_mem_descs_size;
+ dma_addr_t host_mem_descs_dma;
+ struct nvme_host_mem_buf_desc *host_mem_descs;
+ void **host_mem_desc_bufs;
+@@ -904,9 +905,10 @@ static blk_status_t nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
+
+ static void nvme_submit_cmds(struct nvme_queue *nvmeq, struct request **rqlist)
+ {
++ struct request *req;
++
+ spin_lock(&nvmeq->sq_lock);
+- while (!rq_list_empty(*rqlist)) {
+- struct request *req = rq_list_pop(rqlist);
++ while ((req = rq_list_pop(rqlist))) {
+ struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+
+ nvme_sq_copy_cmd(nvmeq, &iod->cmd);
+@@ -932,31 +934,25 @@ static bool nvme_prep_rq_batch(struct nvme_queue *nvmeq, struct request *req)
+
+ static void nvme_queue_rqs(struct request **rqlist)
+ {
+- struct request *req, *next, *prev = NULL;
++ struct request *submit_list = NULL;
+ struct request *requeue_list = NULL;
++ struct request **requeue_lastp = &requeue_list;
++ struct nvme_queue *nvmeq = NULL;
++ struct request *req;
+
+- rq_list_for_each_safe(rqlist, req, next) {
+- struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
+-
+- if (!nvme_prep_rq_batch(nvmeq, req)) {
+- /* detach 'req' and add to remainder list */
+- rq_list_move(rqlist, &requeue_list, req, prev);
+-
+- req = prev;
+- if (!req)
+- continue;
+- }
++ while ((req = rq_list_pop(rqlist))) {
++ if (nvmeq && nvmeq != req->mq_hctx->driver_data)
++ nvme_submit_cmds(nvmeq, &submit_list);
++ nvmeq = req->mq_hctx->driver_data;
+
+- if (!next || req->mq_hctx != next->mq_hctx) {
+- /* detach rest of list, and submit */
+- req->rq_next = NULL;
+- nvme_submit_cmds(nvmeq, rqlist);
+- *rqlist = next;
+- prev = NULL;
+- } else
+- prev = req;
++ if (nvme_prep_rq_batch(nvmeq, req))
++ rq_list_add(&submit_list, req); /* reverse order */
++ else
++ rq_list_add_tail(&requeue_lastp, req);
+ }
+
++ if (nvmeq)
++ nvme_submit_cmds(nvmeq, &submit_list);
+ *rqlist = requeue_list;
+ }
+
+@@ -1929,10 +1925,10 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
+
+ kfree(dev->host_mem_desc_bufs);
+ dev->host_mem_desc_bufs = NULL;
+- dma_free_coherent(dev->dev,
+- dev->nr_host_mem_descs * sizeof(*dev->host_mem_descs),
++ dma_free_coherent(dev->dev, dev->host_mem_descs_size,
+ dev->host_mem_descs, dev->host_mem_descs_dma);
+ dev->host_mem_descs = NULL;
++ dev->host_mem_descs_size = 0;
+ dev->nr_host_mem_descs = 0;
+ }
+
+@@ -1940,7 +1936,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+ u32 chunk_size)
+ {
+ struct nvme_host_mem_buf_desc *descs;
+- u32 max_entries, len;
++ u32 max_entries, len, descs_size;
+ dma_addr_t descs_dma;
+ int i = 0;
+ void **bufs;
+@@ -1953,8 +1949,9 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+ if (dev->ctrl.hmmaxd && dev->ctrl.hmmaxd < max_entries)
+ max_entries = dev->ctrl.hmmaxd;
+
+- descs = dma_alloc_coherent(dev->dev, max_entries * sizeof(*descs),
+- &descs_dma, GFP_KERNEL);
++ descs_size = max_entries * sizeof(*descs);
++ descs = dma_alloc_coherent(dev->dev, descs_size, &descs_dma,
++ GFP_KERNEL);
+ if (!descs)
+ goto out;
+
+@@ -1983,6 +1980,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+ dev->host_mem_size = size;
+ dev->host_mem_descs = descs;
+ dev->host_mem_descs_dma = descs_dma;
++ dev->host_mem_descs_size = descs_size;
+ dev->host_mem_desc_bufs = bufs;
+ return 0;
+
+@@ -1997,8 +1995,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+
+ kfree(bufs);
+ out_free_descs:
+- dma_free_coherent(dev->dev, max_entries * sizeof(*descs), descs,
+- descs_dma);
++ dma_free_coherent(dev->dev, descs_size, descs, descs_dma);
+ out:
+ dev->host_mem_descs = NULL;
+ return -ENOMEM;
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index bf502ba8da9586..366fbdc56dec10 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -471,6 +471,7 @@ int __initdata dt_root_addr_cells;
+ int __initdata dt_root_size_cells;
+
+ void *initial_boot_params __ro_after_init;
++phys_addr_t initial_boot_params_pa __ro_after_init;
+
+ #ifdef CONFIG_OF_EARLY_FLATTREE
+
+@@ -1270,17 +1271,18 @@ static void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+ return ptr;
+ }
+
+-bool __init early_init_dt_verify(void *params)
++bool __init early_init_dt_verify(void *dt_virt, phys_addr_t dt_phys)
+ {
+- if (!params)
++ if (!dt_virt)
+ return false;
+
+ /* check device tree validity */
+- if (fdt_check_header(params))
++ if (fdt_check_header(dt_virt))
+ return false;
+
+ /* Setup flat device-tree pointer */
+- initial_boot_params = params;
++ initial_boot_params = dt_virt;
++ initial_boot_params_pa = dt_phys;
+ of_fdt_crc32 = crc32_be(~0, initial_boot_params,
+ fdt_totalsize(initial_boot_params));
+ return true;
+@@ -1306,11 +1308,11 @@ void __init early_init_dt_scan_nodes(void)
+ early_init_dt_check_for_usable_mem_range();
+ }
+
+-bool __init early_init_dt_scan(void *params)
++bool __init early_init_dt_scan(void *dt_virt, phys_addr_t dt_phys)
+ {
+ bool status;
+
+- status = early_init_dt_verify(params);
++ status = early_init_dt_verify(dt_virt, dt_phys);
+ if (!status)
+ return false;
+
+diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
+index 68278340cecfe5..3b98a57f1f0743 100644
+--- a/drivers/of/kexec.c
++++ b/drivers/of/kexec.c
+@@ -301,7 +301,7 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+ }
+
+ /* Remove memory reservation for the current device tree. */
+- ret = fdt_find_and_del_mem_rsv(fdt, __pa(initial_boot_params),
++ ret = fdt_find_and_del_mem_rsv(fdt, initial_boot_params_pa,
+ fdt_totalsize(initial_boot_params));
+ if (ret == -EINVAL) {
+ pr_err("Error removing memory reservation.\n");
+diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
+index 4f58345b5c683d..7986113adc7d31 100644
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -4017,10 +4017,6 @@ static int __init of_unittest(void)
+ add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
+
+ /* adding data for unittest */
+-
+- if (IS_ENABLED(CONFIG_UML))
+- unittest_unflatten_overlay_base();
+-
+ res = unittest_data_add();
+ if (res)
+ return res;
+diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
+index 2c87e7728a653b..f76a358e2b5b6f 100644
+--- a/drivers/pci/controller/cadence/pci-j721e.c
++++ b/drivers/pci/controller/cadence/pci-j721e.c
+@@ -7,6 +7,8 @@
+ */
+
+ #include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/container_of.h>
+ #include <linux/delay.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/io.h>
+@@ -22,6 +24,8 @@
+ #include "../../pci.h"
+ #include "pcie-cadence.h"
+
++#define cdns_pcie_to_rc(p) container_of(p, struct cdns_pcie_rc, pcie)
++
+ #define ENABLE_REG_SYS_2 0x108
+ #define STATUS_REG_SYS_2 0x508
+ #define STATUS_CLR_REG_SYS_2 0x708
+@@ -42,18 +46,17 @@ enum link_status {
+ };
+
+ #define J721E_MODE_RC BIT(7)
+-#define LANE_COUNT_MASK BIT(8)
+ #define LANE_COUNT(n) ((n) << 8)
+
+ #define GENERATION_SEL_MASK GENMASK(1, 0)
+
+-#define MAX_LANES 2
+-
+ struct j721e_pcie {
+ struct cdns_pcie *cdns_pcie;
+ struct clk *refclk;
+ u32 mode;
+ u32 num_lanes;
++ u32 max_lanes;
++ struct gpio_desc *reset_gpio;
+ void __iomem *user_cfg_base;
+ void __iomem *intd_cfg_base;
+ u32 linkdown_irq_regfield;
+@@ -71,6 +74,7 @@ struct j721e_pcie_data {
+ unsigned int quirk_disable_flr:1;
+ u32 linkdown_irq_regfield;
+ unsigned int byte_access_allowed:1;
++ unsigned int max_lanes;
+ };
+
+ static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
+@@ -206,11 +210,15 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
+ {
+ struct device *dev = pcie->cdns_pcie->dev;
+ u32 lanes = pcie->num_lanes;
++ u32 mask = BIT(8);
+ u32 val = 0;
+ int ret;
+
++ if (pcie->max_lanes == 4)
++ mask = GENMASK(9, 8);
++
+ val = LANE_COUNT(lanes - 1);
+- ret = regmap_update_bits(syscon, offset, LANE_COUNT_MASK, val);
++ ret = regmap_update_bits(syscon, offset, mask, val);
+ if (ret)
+ dev_err(dev, "failed to set link count\n");
+
+@@ -290,11 +298,13 @@ static const struct j721e_pcie_data j721e_pcie_rc_data = {
+ .quirk_retrain_flag = true,
+ .byte_access_allowed = false,
+ .linkdown_irq_regfield = LINK_DOWN,
++ .max_lanes = 2,
+ };
+
+ static const struct j721e_pcie_data j721e_pcie_ep_data = {
+ .mode = PCI_MODE_EP,
+ .linkdown_irq_regfield = LINK_DOWN,
++ .max_lanes = 2,
+ };
+
+ static const struct j721e_pcie_data j7200_pcie_rc_data = {
+@@ -302,23 +312,27 @@ static const struct j721e_pcie_data j7200_pcie_rc_data = {
+ .quirk_detect_quiet_flag = true,
+ .linkdown_irq_regfield = J7200_LINK_DOWN,
+ .byte_access_allowed = true,
++ .max_lanes = 2,
+ };
+
+ static const struct j721e_pcie_data j7200_pcie_ep_data = {
+ .mode = PCI_MODE_EP,
+ .quirk_detect_quiet_flag = true,
+ .quirk_disable_flr = true,
++ .max_lanes = 2,
+ };
+
+ static const struct j721e_pcie_data am64_pcie_rc_data = {
+ .mode = PCI_MODE_RC,
+ .linkdown_irq_regfield = J7200_LINK_DOWN,
+ .byte_access_allowed = true,
++ .max_lanes = 1,
+ };
+
+ static const struct j721e_pcie_data am64_pcie_ep_data = {
+ .mode = PCI_MODE_EP,
+ .linkdown_irq_regfield = J7200_LINK_DOWN,
++ .max_lanes = 1,
+ };
+
+ static const struct of_device_id of_j721e_pcie_match[] = {
+@@ -432,9 +446,13 @@ static int j721e_pcie_probe(struct platform_device *pdev)
+ pcie->user_cfg_base = base;
+
+ ret = of_property_read_u32(node, "num-lanes", &num_lanes);
+- if (ret || num_lanes > MAX_LANES)
++ if (ret || num_lanes > data->max_lanes) {
++ dev_warn(dev, "num-lanes property not provided or invalid, setting num-lanes to 1\n");
+ num_lanes = 1;
++ }
++
+ pcie->num_lanes = num_lanes;
++ pcie->max_lanes = data->max_lanes;
+
+ if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)))
+ return -EINVAL;
+@@ -475,6 +493,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
+ dev_err(dev, "Failed to get reset GPIO\n");
+ goto err_get_sync;
+ }
++ pcie->reset_gpio = gpiod;
+
+ ret = cdns_pcie_init_phy(dev, cdns_pcie);
+ if (ret) {
+@@ -497,15 +516,14 @@ static int j721e_pcie_probe(struct platform_device *pdev)
+ pcie->refclk = clk;
+
+ /*
+- * "Power Sequencing and Reset Signal Timings" table in
+- * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0
+- * indicates PERST# should be deasserted after minimum of 100us
+- * once REFCLK is stable. The REFCLK to the connector in RC
+- * mode is selected while enabling the PHY. So deassert PERST#
+- * after 100 us.
++ * Section 2.2 of the PCI Express Card Electromechanical
++ * Specification (Revision 5.1) mandates that the deassertion
++ * of the PERST# signal should be delayed by 100 ms (TPVPERL).
++ * This shall ensure that the power and the reference clock
++ * are stable.
+ */
+ if (gpiod) {
+- usleep_range(100, 200);
++ msleep(PCIE_T_PVPERL_MS);
+ gpiod_set_value_cansleep(gpiod, 1);
+ }
+
+@@ -554,6 +572,86 @@ static void j721e_pcie_remove(struct platform_device *pdev)
+ pm_runtime_disable(dev);
+ }
+
++static int j721e_pcie_suspend_noirq(struct device *dev)
++{
++ struct j721e_pcie *pcie = dev_get_drvdata(dev);
++
++ if (pcie->mode == PCI_MODE_RC) {
++ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
++ clk_disable_unprepare(pcie->refclk);
++ }
++
++ cdns_pcie_disable_phy(pcie->cdns_pcie);
++
++ return 0;
++}
++
++static int j721e_pcie_resume_noirq(struct device *dev)
++{
++ struct j721e_pcie *pcie = dev_get_drvdata(dev);
++ struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
++ int ret;
++
++ ret = j721e_pcie_ctrl_init(pcie);
++ if (ret < 0)
++ return ret;
++
++ j721e_pcie_config_link_irq(pcie);
++
++ /*
++ * This is not called explicitly in the probe, it is called by
++ * cdns_pcie_init_phy().
++ */
++ ret = cdns_pcie_enable_phy(pcie->cdns_pcie);
++ if (ret < 0)
++ return ret;
++
++ if (pcie->mode == PCI_MODE_RC) {
++ struct cdns_pcie_rc *rc = cdns_pcie_to_rc(cdns_pcie);
++
++ ret = clk_prepare_enable(pcie->refclk);
++ if (ret < 0)
++ return ret;
++
++ /*
++ * Section 2.2 of the PCI Express Card Electromechanical
++ * Specification (Revision 5.1) mandates that the deassertion
++ * of the PERST# signal should be delayed by 100 ms (TPVPERL).
++ * This shall ensure that the power and the reference clock
++ * are stable.
++ */
++ if (pcie->reset_gpio) {
++ msleep(PCIE_T_PVPERL_MS);
++ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
++ }
++
++ ret = cdns_pcie_host_link_setup(rc);
++ if (ret < 0) {
++ clk_disable_unprepare(pcie->refclk);
++ return ret;
++ }
++
++ /*
++ * Reset internal status of BARs to force reinitialization in
++ * cdns_pcie_host_init().
++ */
++ for (enum cdns_pcie_rp_bar bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
++ rc->avail_ib_bar[bar] = true;
++
++ ret = cdns_pcie_host_init(rc);
++ if (ret) {
++ clk_disable_unprepare(pcie->refclk);
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++static DEFINE_NOIRQ_DEV_PM_OPS(j721e_pcie_pm_ops,
++ j721e_pcie_suspend_noirq,
++ j721e_pcie_resume_noirq);
++
+ static struct platform_driver j721e_pcie_driver = {
+ .probe = j721e_pcie_probe,
+ .remove_new = j721e_pcie_remove,
+@@ -561,6 +659,7 @@ static struct platform_driver j721e_pcie_driver = {
+ .name = "j721e-pcie",
+ .of_match_table = of_j721e_pcie_match,
+ .suppress_bind_attrs = true,
++ .pm = pm_sleep_ptr(&j721e_pcie_pm_ops),
+ },
+ };
+ builtin_platform_driver(j721e_pcie_driver);
+diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
+index 5b14f7ee3c798e..8af95e9da7cec6 100644
+--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
++++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
+@@ -485,8 +485,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
+ return cdns_pcie_host_map_dma_ranges(rc);
+ }
+
+-static int cdns_pcie_host_init(struct device *dev,
+- struct cdns_pcie_rc *rc)
++int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
+ {
+ int err;
+
+@@ -497,6 +496,30 @@ static int cdns_pcie_host_init(struct device *dev,
+ return cdns_pcie_host_init_address_translation(rc);
+ }
+
++int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
++{
++ struct cdns_pcie *pcie = &rc->pcie;
++ struct device *dev = rc->pcie.dev;
++ int ret;
++
++ if (rc->quirk_detect_quiet_flag)
++ cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
++
++ cdns_pcie_host_enable_ptm_response(pcie);
++
++ ret = cdns_pcie_start_link(pcie);
++ if (ret) {
++ dev_err(dev, "Failed to start link\n");
++ return ret;
++ }
++
++ ret = cdns_pcie_host_start_link(rc);
++ if (ret)
++ dev_dbg(dev, "PCIe link never came up\n");
++
++ return 0;
++}
++
+ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
+ {
+ struct device *dev = rc->pcie.dev;
+@@ -533,25 +556,14 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
+ return PTR_ERR(rc->cfg_base);
+ rc->cfg_res = res;
+
+- if (rc->quirk_detect_quiet_flag)
+- cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
+-
+- cdns_pcie_host_enable_ptm_response(pcie);
+-
+- ret = cdns_pcie_start_link(pcie);
+- if (ret) {
+- dev_err(dev, "Failed to start link\n");
+- return ret;
+- }
+-
+- ret = cdns_pcie_host_start_link(rc);
++ ret = cdns_pcie_host_link_setup(rc);
+ if (ret)
+- dev_dbg(dev, "PCIe link never came up\n");
++ return ret;
+
+ for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
+ rc->avail_ib_bar[bar] = true;
+
+- ret = cdns_pcie_host_init(dev, rc);
++ ret = cdns_pcie_host_init(rc);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
+index 373cb50fcd159d..d55dfd173f228f 100644
+--- a/drivers/pci/controller/cadence/pcie-cadence.h
++++ b/drivers/pci/controller/cadence/pcie-cadence.h
+@@ -515,10 +515,22 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
+ }
+
+ #ifdef CONFIG_PCIE_CADENCE_HOST
++int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
++int cdns_pcie_host_init(struct cdns_pcie_rc *rc);
+ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
+ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where);
+ #else
++static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
++{
++ return 0;
++}
++
++static inline int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
++{
++ return 0;
++}
++
+ static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
+ {
+ return 0;
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index c5475830c835f5..bf9a961c9f2766 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -464,6 +464,17 @@ static void __iomem *ks_pcie_other_map_bus(struct pci_bus *bus,
+ struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
+ u32 reg;
+
++ /*
++ * Checking whether the link is up here is a last line of defense
++ * against platforms that forward errors on the system bus as
++ * SError upon PCI configuration transactions issued when the link
++ * is down. This check is racy by definition and does not stop
++ * the system from triggering an SError if the link goes down
++ * after this check is performed.
++ */
++ if (!dw_pcie_link_up(pci))
++ return NULL;
++
+ reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) |
+ CFG_FUNC(PCI_FUNC(devfn));
+ if (!pci_is_root_bus(bus->parent))
+@@ -1104,6 +1115,7 @@ static int ks_pcie_am654_set_mode(struct device *dev,
+
+ static const struct ks_pcie_of_data ks_pcie_rc_of_data = {
+ .host_ops = &ks_pcie_host_ops,
++ .mode = DW_PCIE_RC_TYPE,
+ .version = DW_PCIE_VER_365A,
+ };
+
+diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
+index 1e3c3192d122cb..954b773eebb197 100644
+--- a/drivers/pci/controller/pcie-rockchip-ep.c
++++ b/drivers/pci/controller/pcie-rockchip-ep.c
+@@ -63,15 +63,25 @@ static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip,
+ ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region));
+ }
+
++static int rockchip_pcie_ep_ob_atu_num_bits(struct rockchip_pcie *rockchip,
++ u64 pci_addr, size_t size)
++{
++ int num_pass_bits = fls64(pci_addr ^ (pci_addr + size - 1));
++
++ return clamp(num_pass_bits,
++ ROCKCHIP_PCIE_AT_MIN_NUM_BITS,
++ ROCKCHIP_PCIE_AT_MAX_NUM_BITS);
++}
++
+ static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
+ u32 r, u64 cpu_addr, u64 pci_addr,
+ size_t size)
+ {
+- int num_pass_bits = fls64(size - 1);
++ int num_pass_bits;
+ u32 addr0, addr1, desc0;
+
+- if (num_pass_bits < 8)
+- num_pass_bits = 8;
++ num_pass_bits = rockchip_pcie_ep_ob_atu_num_bits(rockchip,
++ pci_addr, size);
+
+ addr0 = ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
+ (lower_32_bits(pci_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
+diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
+index 6111de35f84ca2..15ee949f2485e3 100644
+--- a/drivers/pci/controller/pcie-rockchip.h
++++ b/drivers/pci/controller/pcie-rockchip.h
+@@ -245,6 +245,10 @@
+ (PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12)))
+ #define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE(fn) \
+ (PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12)))
++
++#define ROCKCHIP_PCIE_AT_MIN_NUM_BITS 8
++#define ROCKCHIP_PCIE_AT_MAX_NUM_BITS 20
++
+ #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
+ (PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008)
+ #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
+diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/endpoint/functions/pci-epf-mhi.c
+index 34e7191f950867..87154992ea11b9 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-mhi.c
++++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c
+@@ -600,12 +600,18 @@ static int pci_epf_mhi_bind(struct pci_epf *epf)
+ {
+ struct pci_epf_mhi *epf_mhi = epf_get_drvdata(epf);
+ struct pci_epc *epc = epf->epc;
++ struct device *dev = &epf->dev;
+ struct platform_device *pdev = to_platform_device(epc->dev.parent);
+ struct resource *res;
+ int ret;
+
+ /* Get MMIO base address from Endpoint controller */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mmio");
++ if (!res) {
++ dev_err(dev, "Failed to get \"mmio\" resource\n");
++ return -ENODEV;
++ }
++
+ epf_mhi->mmio_phys = res->start;
+ epf_mhi->mmio_size = resource_size(res);
+
+diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
+index a7d3a92391a418..d06623c751f84e 100644
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -663,18 +663,18 @@ void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
+ if (!epc || IS_ERR(epc) || !epf)
+ return;
+
++ mutex_lock(&epc->list_lock);
+ if (type == PRIMARY_INTERFACE) {
+ func_no = epf->func_no;
+ list = &epf->list;
++ epf->epc = NULL;
+ } else {
+ func_no = epf->sec_epc_func_no;
+ list = &epf->sec_epc_list;
++ epf->sec_epc = NULL;
+ }
+-
+- mutex_lock(&epc->list_lock);
+ clear_bit(func_no, &epc->function_num_map);
+ list_del(list);
+- epf->epc = NULL;
+ mutex_unlock(&epc->list_lock);
+ }
+ EXPORT_SYMBOL_GPL(pci_epc_remove_epf);
+diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
+index 3b248426a9f424..a35af42d6a3d8f 100644
+--- a/drivers/pci/hotplug/cpqphp_pci.c
++++ b/drivers/pci/hotplug/cpqphp_pci.c
+@@ -135,11 +135,13 @@ int cpqhp_unconfigure_device(struct pci_func *func)
+ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
+ {
+ u32 vendID = 0;
++ int ret;
+
+- if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
+- return -1;
+- if (vendID == 0xffffffff)
+- return -1;
++ ret = pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID);
++ if (ret != PCIBIOS_SUCCESSFUL)
++ return PCIBIOS_DEVICE_NOT_FOUND;
++ if (PCI_POSSIBLE_ERROR(vendID))
++ return PCIBIOS_DEVICE_NOT_FOUND;
+ return pci_bus_read_config_dword(bus, devfn, offset, value);
+ }
+
+@@ -202,13 +204,15 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_
+ {
+ u16 tdevice;
+ u32 work;
++ int ret;
+ u8 tbus;
+
+ ctrl->pci_bus->number = bus_num;
+
+ for (tdevice = 0; tdevice < 0xFF; tdevice++) {
+ /* Scan for access first */
+- if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
++ ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work);
++ if (ret)
+ continue;
+ dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
+ /* Yep we got one. Not a bridge ? */
+@@ -220,7 +224,8 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_
+ }
+ for (tdevice = 0; tdevice < 0xFF; tdevice++) {
+ /* Scan for access first */
+- if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
++ ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work);
++ if (ret)
+ continue;
+ dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
+ /* Yep we got one. bridge ? */
+@@ -253,7 +258,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
+ *dev_num = tdevice;
+ ctrl->pci_bus->number = tbus;
+ pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
+- if (!nobridge || (work == 0xffffffff))
++ if (!nobridge || PCI_POSSIBLE_ERROR(work))
+ return 0;
+
+ dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
+diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
+index 03539e5053720f..ec63e9b9e238f5 100644
+--- a/drivers/pci/of_property.c
++++ b/drivers/pci/of_property.c
+@@ -126,7 +126,7 @@ static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *ocs,
+ if (of_pci_get_addr_flags(&res[j], &flags))
+ continue;
+
+- val64 = res[j].start;
++ val64 = pci_bus_address(pdev, &res[j] - pdev->resource);
+ of_pci_set_address(pdev, rp[i].parent_addr, val64, 0, flags,
+ false);
+ if (pci_is_bridge(pdev)) {
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 93f2f4dcf6d696..830877efe50597 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -5444,7 +5444,7 @@ static ssize_t reset_method_store(struct device *dev,
+ const char *buf, size_t count)
+ {
+ struct pci_dev *pdev = to_pci_dev(dev);
+- char *options, *name;
++ char *options, *tmp_options, *name;
+ int m, n;
+ u8 reset_methods[PCI_NUM_RESET_METHODS] = { 0 };
+
+@@ -5464,7 +5464,8 @@ static ssize_t reset_method_store(struct device *dev,
+ return -ENOMEM;
+
+ n = 0;
+- while ((name = strsep(&options, " ")) != NULL) {
++ tmp_options = options;
++ while ((name = strsep(&tmp_options, " ")) != NULL) {
+ if (sysfs_streq(name, ""))
+ continue;
+
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index d5e9010a135a14..67ec4cf2fdb4c6 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -13,6 +13,9 @@
+
+ #define PCIE_LINK_RETRAIN_TIMEOUT_MS 1000
+
++/* Power stable to PERST# inactive from PCIe card Electromechanical Spec */
++#define PCIE_T_PVPERL_MS 100
++
+ /*
+ * PCIe r6.0, sec 5.3.3.2.1 <PME Synchronization>
+ * Recommends 1ms to 10ms timeout to check L2 ready.
+diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
+index 0f87cade10f74b..ed645c7a4e4b41 100644
+--- a/drivers/pci/slot.c
++++ b/drivers/pci/slot.c
+@@ -79,6 +79,7 @@ static void pci_slot_release(struct kobject *kobj)
+ up_read(&pci_bus_sem);
+
+ list_del(&slot->list);
++ pci_bus_put(slot->bus);
+
+ kfree(slot);
+ }
+@@ -261,7 +262,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
+ goto err;
+ }
+
+- slot->bus = parent;
++ slot->bus = pci_bus_get(parent);
+ slot->number = slot_nr;
+
+ slot->kobj.kset = pci_slots_kset;
+@@ -269,6 +270,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
+ slot_name = make_slot_name(name);
+ if (!slot_name) {
+ err = -ENOMEM;
++ pci_bus_put(slot->bus);
+ kfree(slot);
+ goto err;
+ }
+diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
+index 0b3ce77136456a..7bd1733d797703 100644
+--- a/drivers/perf/arm-cmn.c
++++ b/drivers/perf/arm-cmn.c
+@@ -2075,8 +2075,6 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
+ continue;
+
+ xp = arm_cmn_node_to_xp(cmn, dn);
+- dn->portid_bits = xp->portid_bits;
+- dn->deviceid_bits = xp->deviceid_bits;
+ dn->dtc = xp->dtc;
+ dn->dtm = xp->dtm;
+ if (cmn->multi_dtm)
+@@ -2307,6 +2305,8 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
+ }
+
+ arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn);
++ dn->portid_bits = xp->portid_bits;
++ dn->deviceid_bits = xp->deviceid_bits;
+
+ switch (dn->type) {
+ case CMN_TYPE_DTC:
+diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
+index 6303b82566f981..31e491e7f2065a 100644
+--- a/drivers/perf/arm_smmuv3_pmu.c
++++ b/drivers/perf/arm_smmuv3_pmu.c
+@@ -431,6 +431,17 @@ static int smmu_pmu_event_init(struct perf_event *event)
+ return -EINVAL;
+ }
+
++ /*
++ * Ensure all events are on the same cpu so all events are in the
++ * same cpu context, to avoid races on pmu_enable etc.
++ */
++ event->cpu = smmu_pmu->on_cpu;
++
++ hwc->idx = -1;
++
++ if (event->group_leader == event)
++ return 0;
++
+ for_each_sibling_event(sibling, event->group_leader) {
+ if (is_software_event(sibling))
+ continue;
+@@ -442,14 +453,6 @@ static int smmu_pmu_event_init(struct perf_event *event)
+ return -EINVAL;
+ }
+
+- hwc->idx = -1;
+-
+- /*
+- * Ensure all events are on the same cpu so all events are in the
+- * same cpu context, to avoid races on pmu_enable etc.
+- */
+- event->cpu = smmu_pmu->on_cpu;
+-
+ return 0;
+ }
+
+diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
+index b6d1ed9ec9a3c9..7c05dbf533e7a3 100644
+--- a/drivers/pinctrl/pinctrl-k210.c
++++ b/drivers/pinctrl/pinctrl-k210.c
+@@ -183,7 +183,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = {
+ [K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
+ };
+
+-#undef DEFAULT
++#undef K210_PC_DEFAULT
+
+ /*
+ * Pin functions configuration information.
+diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
+index f2be341f73e13e..1528f4097ff8a3 100644
+--- a/drivers/pinctrl/pinctrl-zynqmp.c
++++ b/drivers/pinctrl/pinctrl-zynqmp.c
+@@ -48,7 +48,6 @@
+ * @name: Name of the pin mux function
+ * @groups: List of pin groups for this function
+ * @ngroups: Number of entries in @groups
+- * @node: Firmware node matching with the function
+ *
+ * This structure holds information about pin control function
+ * and function group names supporting that function.
+diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+index 5817c52cee6bad..8acaae88b87e8b 100644
+--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
++++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+@@ -667,7 +667,7 @@ static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev,
+ "push-pull", "open-drain", "open-source"
+ };
+ static const char *const strengths[] = {
+- "no", "high", "medium", "low"
++ "no", "low", "medium", "high"
+ };
+
+ pad = pctldev->desc->pins[pin].drv_data;
+diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
+index d0b4d3fc40ed8f..66fdc6fa73ec54 100644
+--- a/drivers/platform/chrome/cros_ec_typec.c
++++ b/drivers/platform/chrome/cros_ec_typec.c
+@@ -390,6 +390,7 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
+ return 0;
+
+ unregister_ports:
++ fwnode_handle_put(fwnode);
+ cros_unregister_ports(typec);
+ return ret;
+ }
+diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
+index 6fb538a1386894..9a9b9feac41664 100644
+--- a/drivers/platform/x86/dell/dell-smbios-base.c
++++ b/drivers/platform/x86/dell/dell-smbios-base.c
+@@ -544,6 +544,7 @@ static int __init dell_smbios_init(void)
+ int ret, wmi, smm;
+
+ if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) &&
++ !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Alienware", NULL) &&
+ !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) {
+ pr_err("Unable to run on non-Dell system\n");
+ return -ENODEV;
+diff --git a/drivers/platform/x86/dell/dell-wmi-base.c b/drivers/platform/x86/dell/dell-wmi-base.c
+index 24fd7ffadda952..841a5414d28a68 100644
+--- a/drivers/platform/x86/dell/dell-wmi-base.c
++++ b/drivers/platform/x86/dell/dell-wmi-base.c
+@@ -80,6 +80,12 @@ static const struct dmi_system_id dell_wmi_smbios_list[] __initconst = {
+ static const struct key_entry dell_wmi_keymap_type_0000[] = {
+ { KE_IGNORE, 0x003a, { KEY_CAPSLOCK } },
+
++ /* Meta key lock */
++ { KE_IGNORE, 0xe000, { KEY_RIGHTMETA } },
++
++ /* Meta key unlock */
++ { KE_IGNORE, 0xe001, { KEY_RIGHTMETA } },
++
+ /* Key code is followed by brightness level */
+ { KE_KEY, 0xe005, { KEY_BRIGHTNESSDOWN } },
+ { KE_KEY, 0xe006, { KEY_BRIGHTNESSUP } },
+diff --git a/drivers/platform/x86/intel/bxtwc_tmu.c b/drivers/platform/x86/intel/bxtwc_tmu.c
+index d0e2a3c293b0b0..9ac801b929b93c 100644
+--- a/drivers/platform/x86/intel/bxtwc_tmu.c
++++ b/drivers/platform/x86/intel/bxtwc_tmu.c
+@@ -48,9 +48,8 @@ static irqreturn_t bxt_wcove_tmu_irq_handler(int irq, void *data)
+ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
+ {
+ struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
+- struct regmap_irq_chip_data *regmap_irq_chip;
+ struct wcove_tmu *wctmu;
+- int ret, virq, irq;
++ int ret;
+
+ wctmu = devm_kzalloc(&pdev->dev, sizeof(*wctmu), GFP_KERNEL);
+ if (!wctmu)
+@@ -59,27 +58,18 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
+ wctmu->dev = &pdev->dev;
+ wctmu->regmap = pmic->regmap;
+
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
+- return irq;
++ wctmu->irq = platform_get_irq(pdev, 0);
++ if (wctmu->irq < 0)
++ return wctmu->irq;
+
+- regmap_irq_chip = pmic->irq_chip_data_tmu;
+- virq = regmap_irq_get_virq(regmap_irq_chip, irq);
+- if (virq < 0) {
+- dev_err(&pdev->dev,
+- "failed to get virtual interrupt=%d\n", irq);
+- return virq;
+- }
+-
+- ret = devm_request_threaded_irq(&pdev->dev, virq,
++ ret = devm_request_threaded_irq(&pdev->dev, wctmu->irq,
+ NULL, bxt_wcove_tmu_irq_handler,
+ IRQF_ONESHOT, "bxt_wcove_tmu", wctmu);
+ if (ret) {
+ dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n",
+- ret, virq);
++ ret, wctmu->irq);
+ return ret;
+ }
+- wctmu->irq = virq;
+
+ /* Unmask TMU second level Wake & System alarm */
+ regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG,
+diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
+index ebd81846e2d564..7365286f6d2dc1 100644
+--- a/drivers/platform/x86/panasonic-laptop.c
++++ b/drivers/platform/x86/panasonic-laptop.c
+@@ -602,8 +602,7 @@ static ssize_t eco_mode_show(struct device *dev, struct device_attribute *attr,
+ result = 1;
+ break;
+ default:
+- result = -EIO;
+- break;
++ return -EIO;
+ }
+ return sysfs_emit(buf, "%u\n", result);
+ }
+@@ -749,7 +748,12 @@ static ssize_t current_brightness_store(struct device *dev, struct device_attrib
+ static ssize_t cdpower_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+- return sysfs_emit(buf, "%d\n", get_optd_power_state());
++ int state = get_optd_power_state();
++
++ if (state < 0)
++ return state;
++
++ return sysfs_emit(buf, "%d\n", state);
+ }
+
+ static ssize_t cdpower_store(struct device *dev, struct device_attribute *attr,
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 5b1f08eabd9232..964670d4ca1e2a 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -8013,6 +8013,7 @@ static u8 fan_control_resume_level;
+ static int fan_watchdog_maxinterval;
+
+ static bool fan_with_ns_addr;
++static bool ecfw_with_fan_dec_rpm;
+
+ static struct mutex fan_mutex;
+
+@@ -8655,7 +8656,11 @@ static ssize_t fan_fan1_input_show(struct device *dev,
+ if (res < 0)
+ return res;
+
+- return sysfs_emit(buf, "%u\n", speed);
++ /* Check for fan speeds displayed in hexadecimal */
++ if (!ecfw_with_fan_dec_rpm)
++ return sysfs_emit(buf, "%u\n", speed);
++ else
++ return sysfs_emit(buf, "%x\n", speed);
+ }
+
+ static DEVICE_ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL);
+@@ -8672,7 +8677,11 @@ static ssize_t fan_fan2_input_show(struct device *dev,
+ if (res < 0)
+ return res;
+
+- return sysfs_emit(buf, "%u\n", speed);
++ /* Check for fan speeds displayed in hexadecimal */
++ if (!ecfw_with_fan_dec_rpm)
++ return sysfs_emit(buf, "%u\n", speed);
++ else
++ return sysfs_emit(buf, "%x\n", speed);
+ }
+
+ static DEVICE_ATTR(fan2_input, S_IRUGO, fan_fan2_input_show, NULL);
+@@ -8748,6 +8757,7 @@ static const struct attribute_group fan_driver_attr_group = {
+ #define TPACPI_FAN_2CTL 0x0004 /* selects fan2 control */
+ #define TPACPI_FAN_NOFAN 0x0008 /* no fan available */
+ #define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */
++#define TPACPI_FAN_DECRPM 0x0020 /* For ECFW's with RPM in register as decimal */
+
+ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
+ TPACPI_QEC_IBM('1', 'Y', TPACPI_FAN_Q1),
+@@ -8769,6 +8779,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
+ TPACPI_Q_LNV3('R', '1', 'F', TPACPI_FAN_NS), /* L13 Yoga Gen 2 */
+ TPACPI_Q_LNV3('N', '2', 'U', TPACPI_FAN_NS), /* X13 Yoga Gen 2*/
+ TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */
++ TPACPI_Q_LNV3('R', '0', 'Q', TPACPI_FAN_DECRPM),/* L480 */
+ };
+
+ static int __init fan_init(struct ibm_init_struct *iibm)
+@@ -8809,6 +8820,13 @@ static int __init fan_init(struct ibm_init_struct *iibm)
+ tp_features.fan_ctrl_status_undef = 1;
+ }
+
++ /* Check for the EC/BIOS with RPM reported in decimal*/
++ if (quirks & TPACPI_FAN_DECRPM) {
++ pr_info("ECFW with fan RPM as decimal in EC register\n");
++ ecfw_with_fan_dec_rpm = 1;
++ tp_features.fan_ctrl_status_undef = 1;
++ }
++
+ if (gfan_handle) {
+ /* 570, 600e/x, 770e, 770x */
+ fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
+@@ -9020,7 +9038,11 @@ static int fan_read(struct seq_file *m)
+ if (rc < 0)
+ return rc;
+
+- seq_printf(m, "speed:\t\t%d\n", speed);
++ /* Check for fan speeds displayed in hexadecimal */
++ if (!ecfw_with_fan_dec_rpm)
++ seq_printf(m, "speed:\t\t%d\n", speed);
++ else
++ seq_printf(m, "speed:\t\t%x\n", speed);
+
+ if (fan_status_access_mode == TPACPI_FAN_RD_TPEC_NS) {
+ /*
+diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
+index a0fa0b6859c9ca..63a348af83db15 100644
+--- a/drivers/platform/x86/x86-android-tablets/core.c
++++ b/drivers/platform/x86/x86-android-tablets/core.c
+@@ -230,20 +230,20 @@ static void x86_android_tablet_remove(struct platform_device *pdev)
+ {
+ int i;
+
+- for (i = 0; i < serdev_count; i++) {
++ for (i = serdev_count - 1; i >= 0; i--) {
+ if (serdevs[i])
+ serdev_device_remove(serdevs[i]);
+ }
+
+ kfree(serdevs);
+
+- for (i = 0; i < pdev_count; i++)
++ for (i = pdev_count - 1; i >= 0; i--)
+ platform_device_unregister(pdevs[i]);
+
+ kfree(pdevs);
+ kfree(buttons);
+
+- for (i = 0; i < i2c_client_count; i++)
++ for (i = i2c_client_count - 1; i >= 0; i--)
+ i2c_unregister_device(i2c_clients[i]);
+
+ kfree(i2c_clients);
+diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
+index f520228e1b6ae9..4449d36042c22f 100644
+--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
++++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
+@@ -161,6 +161,7 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
+ break;
+
+ if (args.args_count >= 1 && args.np == dev->of_node) {
++ of_node_put(args.np);
+ if (args.args[0] > max_id) {
+ max_id = args.args[0];
+ } else {
+@@ -188,7 +189,10 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
+ pm_genpd_init(&pd->pd, NULL, true);
+
+ list_add(&pd->node, &pd_provider->pd_list);
++ } else {
++ of_node_put(args.np);
+ }
++
+ index++;
+ }
+ }
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 4296600e8912a3..23c87365675742 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -449,9 +449,29 @@ static u8
+ [BQ27XXX_REG_AP] = 0x18,
+ BQ27XXX_DM_REG_ROWS,
+ },
++ bq27426_regs[BQ27XXX_REG_MAX] = {
++ [BQ27XXX_REG_CTRL] = 0x00,
++ [BQ27XXX_REG_TEMP] = 0x02,
++ [BQ27XXX_REG_INT_TEMP] = 0x1e,
++ [BQ27XXX_REG_VOLT] = 0x04,
++ [BQ27XXX_REG_AI] = 0x10,
++ [BQ27XXX_REG_FLAGS] = 0x06,
++ [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
++ [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
++ [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
++ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
++ [BQ27XXX_REG_NAC] = 0x08,
++ [BQ27XXX_REG_RC] = 0x0c,
++ [BQ27XXX_REG_FCC] = 0x0e,
++ [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
++ [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
++ [BQ27XXX_REG_SOC] = 0x1c,
++ [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
++ [BQ27XXX_REG_AP] = 0x18,
++ BQ27XXX_DM_REG_ROWS,
++ },
+ #define bq27411_regs bq27421_regs
+ #define bq27425_regs bq27421_regs
+-#define bq27426_regs bq27421_regs
+ #define bq27441_regs bq27421_regs
+ #define bq27621_regs bq27421_regs
+ bq27z561_regs[BQ27XXX_REG_MAX] = {
+@@ -769,10 +789,23 @@ static enum power_supply_property bq27421_props[] = {
+ };
+ #define bq27411_props bq27421_props
+ #define bq27425_props bq27421_props
+-#define bq27426_props bq27421_props
+ #define bq27441_props bq27421_props
+ #define bq27621_props bq27421_props
+
++static enum power_supply_property bq27426_props[] = {
++ POWER_SUPPLY_PROP_STATUS,
++ POWER_SUPPLY_PROP_PRESENT,
++ POWER_SUPPLY_PROP_VOLTAGE_NOW,
++ POWER_SUPPLY_PROP_CURRENT_NOW,
++ POWER_SUPPLY_PROP_CAPACITY,
++ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
++ POWER_SUPPLY_PROP_TEMP,
++ POWER_SUPPLY_PROP_TECHNOLOGY,
++ POWER_SUPPLY_PROP_CHARGE_FULL,
++ POWER_SUPPLY_PROP_CHARGE_NOW,
++ POWER_SUPPLY_PROP_MANUFACTURER,
++};
++
+ static enum power_supply_property bq27z561_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
+index 416409e2fd6da2..1893d37dd575de 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -480,8 +480,6 @@ EXPORT_SYMBOL_GPL(power_supply_get_by_name);
+ */
+ void power_supply_put(struct power_supply *psy)
+ {
+- might_sleep();
+-
+ atomic_dec(&psy->use_cnt);
+ put_device(&psy->dev);
+ }
+diff --git a/drivers/power/supply/rt9471.c b/drivers/power/supply/rt9471.c
+index 868b0703d15c52..522a67736fa5a9 100644
+--- a/drivers/power/supply/rt9471.c
++++ b/drivers/power/supply/rt9471.c
+@@ -139,6 +139,19 @@ enum {
+ RT9471_PORTSTAT_DCP,
+ };
+
++enum {
++ RT9471_ICSTAT_SLEEP = 0,
++ RT9471_ICSTAT_VBUSRDY,
++ RT9471_ICSTAT_TRICKLECHG,
++ RT9471_ICSTAT_PRECHG,
++ RT9471_ICSTAT_FASTCHG,
++ RT9471_ICSTAT_IEOC,
++ RT9471_ICSTAT_BGCHG,
++ RT9471_ICSTAT_CHGDONE,
++ RT9471_ICSTAT_CHGFAULT,
++ RT9471_ICSTAT_OTG = 15,
++};
++
+ struct rt9471_chip {
+ struct device *dev;
+ struct regmap *regmap;
+@@ -153,8 +166,8 @@ struct rt9471_chip {
+ };
+
+ static const struct reg_field rt9471_reg_fields[F_MAX_FIELDS] = {
+- [F_WDT] = REG_FIELD(RT9471_REG_TOP, 0, 0),
+- [F_WDT_RST] = REG_FIELD(RT9471_REG_TOP, 1, 1),
++ [F_WDT] = REG_FIELD(RT9471_REG_TOP, 0, 1),
++ [F_WDT_RST] = REG_FIELD(RT9471_REG_TOP, 2, 2),
+ [F_CHG_EN] = REG_FIELD(RT9471_REG_FUNC, 0, 0),
+ [F_HZ] = REG_FIELD(RT9471_REG_FUNC, 5, 5),
+ [F_BATFET_DIS] = REG_FIELD(RT9471_REG_FUNC, 7, 7),
+@@ -255,31 +268,32 @@ static int rt9471_get_ieoc(struct rt9471_chip *chip, int *microamp)
+
+ static int rt9471_get_status(struct rt9471_chip *chip, int *status)
+ {
+- unsigned int chg_ready, chg_done, fault_stat;
++ unsigned int ic_stat;
+ int ret;
+
+- ret = regmap_field_read(chip->rm_fields[F_ST_CHG_RDY], &chg_ready);
+- if (ret)
+- return ret;
+-
+- ret = regmap_field_read(chip->rm_fields[F_ST_CHG_DONE], &chg_done);
++ ret = regmap_field_read(chip->rm_fields[F_IC_STAT], &ic_stat);
+ if (ret)
+ return ret;
+
+- ret = regmap_read(chip->regmap, RT9471_REG_STAT1, &fault_stat);
+- if (ret)
+- return ret;
+-
+- fault_stat &= RT9471_CHGFAULT_MASK;
+-
+- if (chg_ready && chg_done)
+- *status = POWER_SUPPLY_STATUS_FULL;
+- else if (chg_ready && fault_stat)
++ switch (ic_stat) {
++ case RT9471_ICSTAT_VBUSRDY:
++ case RT9471_ICSTAT_CHGFAULT:
+ *status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+- else if (chg_ready && !fault_stat)
++ break;
++ case RT9471_ICSTAT_TRICKLECHG ... RT9471_ICSTAT_BGCHG:
+ *status = POWER_SUPPLY_STATUS_CHARGING;
+- else
++ break;
++ case RT9471_ICSTAT_CHGDONE:
++ *status = POWER_SUPPLY_STATUS_FULL;
++ break;
++ case RT9471_ICSTAT_SLEEP:
++ case RT9471_ICSTAT_OTG:
+ *status = POWER_SUPPLY_STATUS_DISCHARGING;
++ break;
++ default:
++ *status = POWER_SUPPLY_STATUS_UNKNOWN;
++ break;
++ }
+
+ return 0;
+ }
+diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
+index 29a3089c534cda..660a71b7263ce0 100644
+--- a/drivers/pwm/pwm-imx27.c
++++ b/drivers/pwm/pwm-imx27.c
+@@ -26,6 +26,7 @@
+ #define MX3_PWMSR 0x04 /* PWM Status Register */
+ #define MX3_PWMSAR 0x0C /* PWM Sample Register */
+ #define MX3_PWMPR 0x10 /* PWM Period Register */
++#define MX3_PWMCNR 0x14 /* PWM Counter Register */
+
+ #define MX3_PWMCR_FWM GENMASK(27, 26)
+ #define MX3_PWMCR_STOPEN BIT(25)
+@@ -217,11 +218,13 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
+ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+ {
+- unsigned long period_cycles, duty_cycles, prescale;
++ unsigned long period_cycles, duty_cycles, prescale, period_us, tmp;
+ struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
+ struct pwm_state cstate;
+ unsigned long long c;
+ unsigned long long clkrate;
++ unsigned long flags;
++ int val;
+ int ret;
+ u32 cr;
+
+@@ -264,7 +267,98 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ pwm_imx27_sw_reset(chip);
+ }
+
+- writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
++ val = readl(imx->mmio_base + MX3_PWMPR);
++ val = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val;
++ cr = readl(imx->mmio_base + MX3_PWMCR);
++ tmp = NSEC_PER_SEC * (u64)(val + 2) * MX3_PWMCR_PRESCALER_GET(cr);
++ tmp = DIV_ROUND_UP_ULL(tmp, clkrate);
++ period_us = DIV_ROUND_UP_ULL(tmp, 1000);
++
++ /*
++ * ERR051198:
++ * PWM: PWM output may not function correctly if the FIFO is empty when
++ * a new SAR value is programmed
++ *
++ * Description:
++ * When the PWM FIFO is empty, a new value programmed to the PWM Sample
++ * register (PWM_PWMSAR) will be directly applied even if the current
++ * timer period has not expired.
++ *
++ * If the new SAMPLE value programmed in the PWM_PWMSAR register is
++ * less than the previous value, and the PWM counter register
++ * (PWM_PWMCNR) that contains the current COUNT value is greater than
++ * the new programmed SAMPLE value, the current period will not flip
++ * the level. This may result in an output pulse with a duty cycle of
++ * 100%.
++ *
++ * Consider a change from
++ * ________
++ * / \______/
++ * ^ * ^
++ * to
++ * ____
++ * / \__________/
++ * ^ ^
++ * At the time marked by *, the new write value will be directly applied
++ * to SAR even the current period is not over if FIFO is empty.
++ *
++ * ________ ____________________
++ * / \______/ \__________/
++ * ^ ^ * ^ ^
++ * |<-- old SAR -->| |<-- new SAR -->|
++ *
++ * That is the output is active for a whole period.
++ *
++ * Workaround:
++ * Check new SAR less than old SAR and current counter is in errata
++ * windows, write extra old SAR into FIFO and new SAR will effect at
++ * next period.
++ *
++ * Sometime period is quite long, such as over 1 second. If add old SAR
++ * into FIFO unconditional, new SAR have to wait for next period. It
++ * may be too long.
++ *
++ * Turn off the interrupt to ensure that not IRQ and schedule happen
++ * during above operations. If any irq and schedule happen, counter
++ * in PWM will be out of data and take wrong action.
++ *
++ * Add a safety margin 1.5us because it needs some time to complete
++ * IO write.
++ *
++ * Use writel_relaxed() to minimize the interval between two writes to
++ * the SAR register to increase the fastest PWM frequency supported.
++ *
++ * When the PWM period is longer than 2us(or <500kHz), this workaround
++ * can solve this problem. No software workaround is available if PWM
++ * period is shorter than IO write. Just try best to fill old data
++ * into FIFO.
++ */
++ c = clkrate * 1500;
++ do_div(c, NSEC_PER_SEC);
++
++ local_irq_save(flags);
++ val = FIELD_GET(MX3_PWMSR_FIFOAV, readl_relaxed(imx->mmio_base + MX3_PWMSR));
++
++ if (duty_cycles < imx->duty_cycle && (cr & MX3_PWMCR_EN)) {
++ if (period_us < 2) { /* 2us = 500 kHz */
++ /* Best effort attempt to fix up >500 kHz case */
++ udelay(3 * period_us);
++ writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR);
++ writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR);
++ } else if (val < MX3_PWMSR_FIFOAV_2WORDS) {
++ val = readl_relaxed(imx->mmio_base + MX3_PWMCNR);
++ /*
++ * If counter is close to period, controller may roll over when
++ * next IO write.
++ */
++ if ((val + c >= duty_cycles && val < imx->duty_cycle) ||
++ val + c >= period_cycles)
++ writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR);
++ }
++ }
++ writel_relaxed(duty_cycles, imx->mmio_base + MX3_PWMSAR);
++ local_irq_restore(flags);
++
+ writel(period_cycles, imx->mmio_base + MX3_PWMPR);
+
+ /*
+diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
+index 867a2cf243f686..374d80dc6d17ab 100644
+--- a/drivers/regulator/rk808-regulator.c
++++ b/drivers/regulator/rk808-regulator.c
+@@ -1286,6 +1286,8 @@ static const struct regulator_desc rk809_reg[] = {
+ .n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+ .vsel_reg = RK817_BUCK3_ON_VSEL_REG,
+ .vsel_mask = RK817_BUCK_VSEL_MASK,
++ .apply_reg = RK817_POWER_CONFIG,
++ .apply_bit = RK817_BUCK3_FB_RES_INTER,
+ .enable_reg = RK817_POWER_EN_REG(0),
+ .enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
+ .enable_val = ENABLE_MASK(RK817_ID_DCDC3),
+@@ -1647,7 +1649,7 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,
+ }
+
+ if (!pdata->dvs_gpio[i]) {
+- dev_info(dev, "there is no dvs%d gpio\n", i);
++ dev_dbg(dev, "there is no dvs%d gpio\n", i);
+ continue;
+ }
+
+@@ -1683,12 +1685,6 @@ static int rk808_regulator_probe(struct platform_device *pdev)
+ if (!pdata)
+ return -ENOMEM;
+
+- ret = rk808_regulator_dt_parse_pdata(&pdev->dev, regmap, pdata);
+- if (ret < 0)
+- return ret;
+-
+- platform_set_drvdata(pdev, pdata);
+-
+ switch (rk808->variant) {
+ case RK805_ID:
+ regulators = rk805_reg;
+@@ -1699,6 +1695,11 @@ static int rk808_regulator_probe(struct platform_device *pdev)
+ nregulators = ARRAY_SIZE(rk806_reg);
+ break;
+ case RK808_ID:
++ /* DVS0/1 GPIOs are supported on the RK808 only */
++ ret = rk808_regulator_dt_parse_pdata(&pdev->dev, regmap, pdata);
++ if (ret < 0)
++ return ret;
++
+ regulators = rk808_reg;
+ nregulators = RK808_NUM_REGULATORS;
+ break;
+@@ -1720,6 +1721,8 @@ static int rk808_regulator_probe(struct platform_device *pdev)
+ return -EINVAL;
+ }
+
++ platform_set_drvdata(pdev, pdata);
++
+ config.dev = &pdev->dev;
+ config.driver_data = pdata;
+ config.regmap = regmap;
+diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
+index 22fe7b5f5236da..2d717f2ed396c6 100644
+--- a/drivers/remoteproc/qcom_q6v5_mss.c
++++ b/drivers/remoteproc/qcom_q6v5_mss.c
+@@ -1161,6 +1161,9 @@ static int q6v5_mba_load(struct q6v5 *qproc)
+ goto disable_active_clks;
+ }
+
++ if (qproc->has_mba_logs)
++ qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE);
++
+ writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
+ if (qproc->dp_size) {
+ writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG);
+@@ -1171,9 +1174,6 @@ static int q6v5_mba_load(struct q6v5 *qproc)
+ if (ret)
+ goto reclaim_mba;
+
+- if (qproc->has_mba_logs)
+- qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE);
+-
+ ret = q6v5_rmb_mba_wait(qproc, 0, 5000);
+ if (ret == -ETIMEDOUT) {
+ dev_err(qproc->dev, "MBA boot timed out\n");
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index b5447dd2dd35e4..6235721f2c1aec 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -832,6 +832,7 @@ static const struct adsp_data sm8250_adsp_resource = {
+ .crash_reason_smem = 423,
+ .firmware_name = "adsp.mdt",
+ .pas_id = 1,
++ .minidump_id = 5,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "lcx",
+@@ -973,6 +974,7 @@ static const struct adsp_data sm8350_cdsp_resource = {
+ .crash_reason_smem = 601,
+ .firmware_name = "cdsp.mdt",
+ .pas_id = 18,
++ .minidump_id = 7,
+ .auto_boot = true,
+ .proxy_pd_names = (char*[]){
+ "cx",
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index d877a1a1aeb4bf..c7f91a82e634f4 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -1117,7 +1117,8 @@ void qcom_glink_native_rx(struct qcom_glink *glink)
+ qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+ break;
+ case GLINK_CMD_OPEN:
+- ret = qcom_glink_rx_defer(glink, param2);
++ /* upper 16 bits of param2 are the "prio" field */
++ ret = qcom_glink_rx_defer(glink, param2 & 0xffff);
+ break;
+ case GLINK_CMD_TX_DATA:
+ case GLINK_CMD_TX_DATA_CONT:
+diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
+index 0b23706d9fd3cc..4a7c41a6c21e7d 100644
+--- a/drivers/rtc/interface.c
++++ b/drivers/rtc/interface.c
+@@ -904,13 +904,18 @@ void rtc_timer_do_work(struct work_struct *work)
+ struct timerqueue_node *next;
+ ktime_t now;
+ struct rtc_time tm;
++ int err;
+
+ struct rtc_device *rtc =
+ container_of(work, struct rtc_device, irqwork);
+
+ mutex_lock(&rtc->ops_lock);
+ again:
+- __rtc_read_time(rtc, &tm);
++ err = __rtc_read_time(rtc, &tm);
++ if (err) {
++ mutex_unlock(&rtc->ops_lock);
++ return;
++ }
+ now = rtc_tm_to_ktime(tm);
+ while ((next = timerqueue_getnext(&rtc->timerqueue))) {
+ if (next->expires > now)
+diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
+index 04e1b8e93bc1cb..79d5ee7b818c57 100644
+--- a/drivers/rtc/rtc-ab-eoz9.c
++++ b/drivers/rtc/rtc-ab-eoz9.c
+@@ -396,13 +396,6 @@ static int abeoz9z3_temp_read(struct device *dev,
+ if (ret < 0)
+ return ret;
+
+- if ((val & ABEOZ9_REG_CTRL_STATUS_V1F) ||
+- (val & ABEOZ9_REG_CTRL_STATUS_V2F)) {
+- dev_err(dev,
+- "thermometer might be disabled due to low voltage\n");
+- return -EINVAL;
+- }
+-
+ switch (attr) {
+ case hwmon_temp_input:
+ ret = regmap_read(regmap, ABEOZ9_REG_REG_TEMP, &val);
+diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
+index 1298962402ff47..3fee27914ba805 100644
+--- a/drivers/rtc/rtc-abx80x.c
++++ b/drivers/rtc/rtc-abx80x.c
+@@ -39,7 +39,7 @@
+ #define ABX8XX_REG_STATUS 0x0f
+ #define ABX8XX_STATUS_AF BIT(2)
+ #define ABX8XX_STATUS_BLF BIT(4)
+-#define ABX8XX_STATUS_WDT BIT(6)
++#define ABX8XX_STATUS_WDT BIT(5)
+
+ #define ABX8XX_REG_CTRL1 0x10
+ #define ABX8XX_CTRL_WRITE BIT(0)
+diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
+index 56ebbd4d048147..8570c8e63d70c3 100644
+--- a/drivers/rtc/rtc-rzn1.c
++++ b/drivers/rtc/rtc-rzn1.c
+@@ -111,8 +111,8 @@ static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm)
+ tm->tm_hour = bcd2bin(tm->tm_hour);
+ tm->tm_wday = bcd2bin(tm->tm_wday);
+ tm->tm_mday = bcd2bin(tm->tm_mday);
+- tm->tm_mon = bcd2bin(tm->tm_mon);
+- tm->tm_year = bcd2bin(tm->tm_year);
++ tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
++ tm->tm_year = bcd2bin(tm->tm_year) + 100;
+
+ return 0;
+ }
+@@ -128,8 +128,8 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
+ tm->tm_hour = bin2bcd(tm->tm_hour);
+ tm->tm_wday = bin2bcd(rzn1_rtc_tm_to_wday(tm));
+ tm->tm_mday = bin2bcd(tm->tm_mday);
+- tm->tm_mon = bin2bcd(tm->tm_mon);
+- tm->tm_year = bin2bcd(tm->tm_year);
++ tm->tm_mon = bin2bcd(tm->tm_mon + 1);
++ tm->tm_year = bin2bcd(tm->tm_year - 100);
+
+ val = readl(rtc->base + RZN1_RTC_CTL2);
+ if (!(val & RZN1_RTC_CTL2_STOPPED)) {
+diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
+index d492a2d26600c1..c6d4522411b312 100644
+--- a/drivers/rtc/rtc-st-lpc.c
++++ b/drivers/rtc/rtc-st-lpc.c
+@@ -218,15 +218,14 @@ static int st_rtc_probe(struct platform_device *pdev)
+ return -EINVAL;
+ }
+
+- ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler, 0,
+- pdev->name, rtc);
++ ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler,
++ IRQF_NO_AUTOEN, pdev->name, rtc);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to request irq %i\n", rtc->irq);
+ return ret;
+ }
+
+ enable_irq_wake(rtc->irq);
+- disable_irq(rtc->irq);
+
+ rtc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(rtc->clk))
+diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
+index 6127add746d181..81ef9002f06400 100644
+--- a/drivers/s390/cio/cio.c
++++ b/drivers/s390/cio/cio.c
+@@ -459,10 +459,14 @@ int cio_update_schib(struct subchannel *sch)
+ {
+ struct schib schib;
+
+- if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
++ if (stsch(sch->schid, &schib))
+ return -ENODEV;
+
+ memcpy(&sch->schib, &schib, sizeof(schib));
++
++ if (!css_sch_is_valid(&schib))
++ return -EACCES;
++
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(cio_update_schib);
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+index 57e0050dbaa538..6b374026cd4f44 100644
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -1387,14 +1387,18 @@ enum io_sch_action {
+ IO_SCH_VERIFY,
+ IO_SCH_DISC,
+ IO_SCH_NOP,
++ IO_SCH_ORPH_CDEV,
+ };
+
+ static enum io_sch_action sch_get_action(struct subchannel *sch)
+ {
+ struct ccw_device *cdev;
++ int rc;
+
+ cdev = sch_get_cdev(sch);
+- if (cio_update_schib(sch)) {
++ rc = cio_update_schib(sch);
++
++ if (rc == -ENODEV) {
+ /* Not operational. */
+ if (!cdev)
+ return IO_SCH_UNREG;
+@@ -1402,6 +1406,16 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
+ return IO_SCH_UNREG;
+ return IO_SCH_ORPH_UNREG;
+ }
++
++ /* Avoid unregistering subchannels without working device. */
++ if (rc == -EACCES) {
++ if (!cdev)
++ return IO_SCH_NOP;
++ if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
++ return IO_SCH_UNREG_CDEV;
++ return IO_SCH_ORPH_CDEV;
++ }
++
+ /* Operational. */
+ if (!cdev)
+ return IO_SCH_ATTACH;
+@@ -1471,6 +1485,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
+ rc = 0;
+ goto out_unlock;
+ case IO_SCH_ORPH_UNREG:
++ case IO_SCH_ORPH_CDEV:
+ case IO_SCH_ORPH_ATTACH:
+ ccw_device_set_disconnected(cdev);
+ break;
+@@ -1502,6 +1517,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
+ /* Handle attached ccw device. */
+ switch (action) {
+ case IO_SCH_ORPH_UNREG:
++ case IO_SCH_ORPH_CDEV:
+ case IO_SCH_ORPH_ATTACH:
+ /* Move ccw device to orphanage. */
+ rc = ccw_device_move_to_orph(cdev);
+diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
+index d2ffdf2491da04..70fcb5c40cfe32 100644
+--- a/drivers/s390/crypto/pkey_api.c
++++ b/drivers/s390/crypto/pkey_api.c
+@@ -1366,9 +1366,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
+ rc = cca_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype,
+ kcs.clrkey.clrkey, kcs.seckey.seckey);
+ DEBUG_DBG("%s cca_clr2seckey()=%d\n", __func__, rc);
+- if (rc)
+- break;
+- if (copy_to_user(ucs, &kcs, sizeof(kcs)))
++ if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
+ rc = -EFAULT;
+ memzero_explicit(&kcs, sizeof(kcs));
+ break;
+@@ -1401,9 +1399,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
+ kcp.protkey.protkey,
+ &kcp.protkey.len, &kcp.protkey.type);
+ DEBUG_DBG("%s pkey_clr2protkey()=%d\n", __func__, rc);
+- if (rc)
+- break;
+- if (copy_to_user(ucp, &kcp, sizeof(kcp)))
++ if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp)))
+ rc = -EFAULT;
+ memzero_explicit(&kcp, sizeof(kcp));
+ break;
+@@ -1555,11 +1551,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
+ if (copy_from_user(&kcs, ucs, sizeof(kcs)))
+ return -EFAULT;
+ apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries);
+- if (IS_ERR(apqns))
++ if (IS_ERR(apqns)) {
++ memzero_explicit(&kcs, sizeof(kcs));
+ return PTR_ERR(apqns);
++ }
+ kkey = kzalloc(klen, GFP_KERNEL);
+ if (!kkey) {
+ kfree(apqns);
++ memzero_explicit(&kcs, sizeof(kcs));
+ return -ENOMEM;
+ }
+ rc = pkey_clr2seckey2(apqns, kcs.apqn_entries,
+@@ -1569,15 +1568,18 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
+ kfree(apqns);
+ if (rc) {
+ kfree(kkey);
++ memzero_explicit(&kcs, sizeof(kcs));
+ break;
+ }
+ if (kcs.key) {
+ if (kcs.keylen < klen) {
+ kfree(kkey);
++ memzero_explicit(&kcs, sizeof(kcs));
+ return -EINVAL;
+ }
+ if (copy_to_user(kcs.key, kkey, klen)) {
+ kfree(kkey);
++ memzero_explicit(&kcs, sizeof(kcs));
+ return -EFAULT;
+ }
+ }
+diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
+index 62cb7a864fd53d..70c7515a822f52 100644
+--- a/drivers/scsi/bfa/bfad.c
++++ b/drivers/scsi/bfa/bfad.c
+@@ -1693,9 +1693,8 @@ bfad_init(void)
+
+ error = bfad_im_module_init();
+ if (error) {
+- error = -ENOMEM;
+ printk(KERN_WARNING "bfad_im_module_init failure\n");
+- goto ext;
++ return -ENOMEM;
+ }
+
+ if (strcmp(FCPI_NAME, " fcpim") == 0)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index e4363b8c6ad268..db9ae206974c21 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1539,10 +1539,16 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
+ /* Init and wait for PHYs to come up and all libsas event finished. */
+ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
++ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+
+- if (!(hisi_hba->phy_state & BIT(phy_no)))
++ if (!sas_phy->phy->enabled)
+ continue;
+
++ if (!(hisi_hba->phy_state & BIT(phy_no))) {
++ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
++ continue;
++ }
++
+ async_schedule_domain(hisi_sas_async_init_wait_phyup,
+ phy, &async);
+ }
+diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
+index 0a01575ab06dd6..0ad8a10002ce36 100644
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -175,7 +175,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
+ ndlp->nlp_state, ndlp->fc4_xpt_flags);
+
+ /* Don't schedule a worker thread event if the vport is going down. */
+- if (vport->load_flag & FC_UNLOADING) {
++ if ((vport->load_flag & FC_UNLOADING) ||
++ !(phba->hba_flag & HBA_SETUP)) {
+ spin_lock_irqsave(&ndlp->lock, iflags);
+ ndlp->rport = NULL;
+
+diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
+index cf506556f3b0bd..070654cc929208 100644
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -5546,11 +5546,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+
+ iocb = &lpfc_cmd->cur_iocbq;
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+- pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
+- if (!pring_s4) {
++ /* if the io_wq & pring are gone, the port was reset. */
++ if (!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq ||
++ !phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring) {
++ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
++ "2877 SCSI Layer I/O Abort Request "
++ "IO CMPL Status x%x ID %d LUN %llu "
++ "HBA_SETUP %d\n", FAILED,
++ cmnd->device->id,
++ (u64)cmnd->device->lun,
++ (HBA_SETUP & phba->hba_flag));
+ ret = FAILED;
+ goto out_unlock_hba;
+ }
++ pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
+ spin_lock(&pring_s4->ring_lock);
+ }
+ /* the command is in process of being cancelled */
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 9cd22588c8eb33..9b1ffa84a06291 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -4684,6 +4684,17 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)
+ /* Look on all the FCP Rings for the iotag */
+ if (phba->sli_rev >= LPFC_SLI_REV4) {
+ for (i = 0; i < phba->cfg_hdw_queue; i++) {
++ if (!phba->sli4_hba.hdwq ||
++ !phba->sli4_hba.hdwq[i].io_wq) {
++ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
++ "7777 hdwq's deleted %lx "
++ "%lx %x %x\n",
++ (unsigned long)phba->pport->load_flag,
++ (unsigned long)phba->hba_flag,
++ phba->link_state,
++ phba->sli.sli_flag);
++ return;
++ }
+ pring = phba->sli4_hba.hdwq[i].io_wq->pring;
+
+ spin_lock_irq(&pring->ring_lock);
+diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
+index 14625e6bc88246..9a81d14aef6b99 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -2737,6 +2737,7 @@ static int qedf_alloc_and_init_sb(struct qedf_ctx *qedf,
+ sb_id, QED_SB_TYPE_STORAGE);
+
+ if (ret) {
++ dma_free_coherent(&qedf->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys);
+ QEDF_ERR(&qedf->dbg_ctx,
+ "Status block initialization failed (0x%x) for id = %d.\n",
+ ret, sb_id);
+diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
+index cd0180b1f5b9da..ede8d1f6ae2361 100644
+--- a/drivers/scsi/qedi/qedi_main.c
++++ b/drivers/scsi/qedi/qedi_main.c
+@@ -369,6 +369,7 @@ static int qedi_alloc_and_init_sb(struct qedi_ctx *qedi,
+ ret = qedi_ops->common->sb_init(qedi->cdev, sb_info, sb_virt, sb_phys,
+ sb_id, QED_SB_TYPE_STORAGE);
+ if (ret) {
++ dma_free_coherent(&qedi->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys);
+ QEDI_ERR(&qedi->dbg_ctx,
+ "Status block initialization failed for id = %d.\n",
+ sb_id);
+diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
+index e6d8beb8777669..dc9722b290f20d 100644
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -307,10 +307,6 @@ sg_open(struct inode *inode, struct file *filp)
+ if (retval)
+ goto sg_put;
+
+- retval = scsi_autopm_get_device(device);
+- if (retval)
+- goto sdp_put;
+-
+ /* scsi_block_when_processing_errors() may block so bypass
+ * check if O_NONBLOCK. Permits SCSI commands to be issued
+ * during error recovery. Tread carefully. */
+@@ -318,7 +314,7 @@ sg_open(struct inode *inode, struct file *filp)
+ scsi_block_when_processing_errors(device))) {
+ retval = -ENXIO;
+ /* we are in error recovery for this device */
+- goto error_out;
++ goto sdp_put;
+ }
+
+ mutex_lock(&sdp->open_rel_lock);
+@@ -371,8 +367,6 @@ sg_open(struct inode *inode, struct file *filp)
+ }
+ error_mutex_locked:
+ mutex_unlock(&sdp->open_rel_lock);
+-error_out:
+- scsi_autopm_put_device(device);
+ sdp_put:
+ kref_put(&sdp->d_ref, sg_device_destroy);
+ scsi_device_put(device);
+@@ -392,7 +386,6 @@ sg_release(struct inode *inode, struct file *filp)
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, "sg_release\n"));
+
+ mutex_lock(&sdp->open_rel_lock);
+- scsi_autopm_put_device(sdp->device);
+ kref_put(&sfp->f_ref, sg_remove_sfp);
+ sdp->open_cnt--;
+
+diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
+index ca4f4ca413f11d..b19388b349be36 100644
+--- a/drivers/sh/intc/core.c
++++ b/drivers/sh/intc/core.c
+@@ -209,7 +209,6 @@ int __init register_intc_controller(struct intc_desc *desc)
+ goto err0;
+
+ INIT_LIST_HEAD(&d->list);
+- list_add_tail(&d->list, &intc_list);
+
+ raw_spin_lock_init(&d->lock);
+ INIT_RADIX_TREE(&d->tree, GFP_ATOMIC);
+@@ -369,6 +368,7 @@ int __init register_intc_controller(struct intc_desc *desc)
+
+ d->skip_suspend = desc->skip_syscore_suspend;
+
++ list_add_tail(&d->list, &intc_list);
+ nr_intc_controllers++;
+
+ return 0;
+diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c
+index 3d0cae30c769ea..06bd94b29fb321 100644
+--- a/drivers/soc/fsl/rcpm.c
++++ b/drivers/soc/fsl/rcpm.c
+@@ -36,6 +36,7 @@ static void copy_ippdexpcr1_setting(u32 val)
+ return;
+
+ regs = of_iomap(np, 0);
++ of_node_put(np);
+ if (!regs)
+ return;
+
+diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
+index ba788762835fad..e339253ccba863 100644
+--- a/drivers/soc/qcom/qcom-geni-se.c
++++ b/drivers/soc/qcom/qcom-geni-se.c
+@@ -586,7 +586,8 @@ int geni_se_clk_tbl_get(struct geni_se *se, unsigned long **tbl)
+
+ for (i = 0; i < MAX_CLK_PERF_LEVEL; i++) {
+ freq = clk_round_rate(se->clk, freq + 1);
+- if (freq <= 0 || freq == se->clk_perf_tbl[i - 1])
++ if (freq <= 0 ||
++ (i > 0 && freq == se->clk_perf_tbl[i - 1]))
+ break;
+ se->clk_perf_tbl[i] = freq;
+ }
+diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
+index 880b41a57da019..2af2b2406fdf39 100644
+--- a/drivers/soc/qcom/socinfo.c
++++ b/drivers/soc/qcom/socinfo.c
+@@ -757,10 +757,16 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
+ qs->attr.revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u.%u",
+ SOCINFO_MAJOR(le32_to_cpu(info->ver)),
+ SOCINFO_MINOR(le32_to_cpu(info->ver)));
+- if (offsetof(struct socinfo, serial_num) <= item_size)
++ if (!qs->attr.soc_id || !qs->attr.revision)
++ return -ENOMEM;
++
++ if (offsetof(struct socinfo, serial_num) <= item_size) {
+ qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "%u",
+ le32_to_cpu(info->serial_num));
++ if (!qs->attr.serial_number)
++ return -ENOMEM;
++ }
+
+ qs->soc_dev = soc_device_register(&qs->attr);
+ if (IS_ERR(qs->soc_dev))
+diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
+index 62b2f1464e4674..55c48ddcf50da4 100644
+--- a/drivers/soc/ti/smartreflex.c
++++ b/drivers/soc/ti/smartreflex.c
+@@ -202,10 +202,10 @@ static int sr_late_init(struct omap_sr *sr_info)
+
+ if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
+ ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq,
+- sr_interrupt, 0, sr_info->name, sr_info);
++ sr_interrupt, IRQF_NO_AUTOEN,
++ sr_info->name, sr_info);
+ if (ret)
+ goto error;
+- disable_irq(sr_info->irq);
+ }
+
+ return ret;
+diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c
+index 098a2ecfd5c689..8f6a2614d8eb41 100644
+--- a/drivers/soc/xilinx/xlnx_event_manager.c
++++ b/drivers/soc/xilinx/xlnx_event_manager.c
+@@ -174,8 +174,10 @@ static int xlnx_add_cb_for_suspend(event_cb_func_t cb_fun, void *data)
+ INIT_LIST_HEAD(&eve_data->cb_list_head);
+
+ cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL);
+- if (!cb_data)
++ if (!cb_data) {
++ kfree(eve_data);
+ return -ENOMEM;
++ }
+ cb_data->eve_cb = cb_fun;
+ cb_data->agent_data = data;
+
+diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
+index 6f9e9d87167758..e7ae7cb4b92a8b 100644
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -183,7 +183,7 @@ static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)
+ case QSPI_MR:
+ return "MR";
+ case QSPI_RD:
+- return "MR";
++ return "RD";
+ case QSPI_TD:
+ return "TD";
+ case QSPI_SR:
+diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
+index 13313f07839b6f..514a2c5c84226c 100644
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -891,7 +891,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0,
++ ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, IRQF_NO_AUTOEN,
+ dev_name(&pdev->dev), fsl_lpspi);
+ if (ret) {
+ dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
+@@ -948,14 +948,10 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+ ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller);
+ if (ret == -EPROBE_DEFER)
+ goto out_pm_get;
+- if (ret < 0)
++ if (ret < 0) {
+ dev_warn(&pdev->dev, "dma setup error %d, use pio\n", ret);
+- else
+- /*
+- * disable LPSPI module IRQ when enable DMA mode successfully,
+- * to prevent the unexpected LPSPI module IRQ events.
+- */
+- disable_irq(irq);
++ enable_irq(irq);
++ }
+
+ ret = devm_spi_register_controller(&pdev->dev, controller);
+ if (ret < 0) {
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index e9ad9b0b598b50..d1afa4140e8a26 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -341,7 +341,7 @@ tegra_qspi_fill_tx_fifo_from_client_txbuf(struct tegra_qspi *tqspi, struct spi_t
+ for (count = 0; count < max_n_32bit; count++) {
+ u32 x = 0;
+
+- for (i = 0; len && (i < bytes_per_word); i++, len--)
++ for (i = 0; len && (i < min(4, bytes_per_word)); i++, len--)
+ x |= (u32)(*tx_buf++) << (i * 8);
+ tegra_qspi_writel(tqspi, x, QSPI_TX_FIFO);
+ }
+diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
+index 9a46b2478f4e98..3503e6c0a5c983 100644
+--- a/drivers/spi/spi-zynqmp-gqspi.c
++++ b/drivers/spi/spi-zynqmp-gqspi.c
+@@ -1341,6 +1341,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
+
+ clk_dis_all:
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ clk_disable_unprepare(xqspi->refclk);
+@@ -1371,6 +1372,7 @@ static void zynqmp_qspi_remove(struct platform_device *pdev)
+ zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
+
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ clk_disable_unprepare(xqspi->refclk);
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 5c57c7378ee708..72e514cee056dd 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -426,6 +426,16 @@ static int spi_probe(struct device *dev)
+ spi->irq = 0;
+ }
+
++ if (has_acpi_companion(dev) && spi->irq < 0) {
++ struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
++
++ spi->irq = acpi_dev_gpio_irq_get(adev, 0);
++ if (spi->irq == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ if (spi->irq < 0)
++ spi->irq = 0;
++ }
++
+ ret = dev_pm_domain_attach(dev, true);
+ if (ret)
+ return ret;
+@@ -2706,9 +2716,6 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
+ acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias,
+ sizeof(spi->modalias));
+
+- if (spi->irq < 0)
+- spi->irq = acpi_dev_gpio_irq_get(adev, 0);
+-
+ acpi_device_set_enumerated(adev);
+
+ adev->power.flags.ignore_parent = true;
+diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
+index 588f2adab058cd..760fe9bef21190 100644
+--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
+@@ -4144,6 +4144,8 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
+ goto err;
+ /* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */
+ me->rgby_data = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL);
++ if (!me->rgby_data)
++ goto err;
+
+ IA_CSS_LEAVE("return=%p", me);
+ return me;
+diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+index ffc2871a021cf6..f252bac676bcaf 100644
+--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
++++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+@@ -144,7 +144,7 @@ static ssize_t current_uuid_show(struct device *dev,
+ struct int3400_thermal_priv *priv = dev_get_drvdata(dev);
+ int i, length = 0;
+
+- if (priv->current_uuid_index > 0)
++ if (priv->current_uuid_index >= 0)
+ return sprintf(buf, "%s\n",
+ int3400_thermal_uuids[priv->current_uuid_index]);
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index d7ac7eef680e12..dad909547179f8 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1336,6 +1336,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ thermal_zone_destroy_device_groups(tz);
+ goto remove_id;
+ }
++ thermal_zone_device_init(tz);
+ result = device_register(&tz->device);
+ if (result)
+ goto release_device;
+@@ -1381,7 +1382,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+
+ INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
+
+- thermal_zone_device_init(tz);
+ /* Update the new thermal zone and mark it as already updated. */
+ if (atomic_cmpxchg(&tz->need_update, 1, 0))
+ thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c
+index e2aa2a1a02ddf5..ecbce226b8747e 100644
+--- a/drivers/tty/serial/8250/8250_fintek.c
++++ b/drivers/tty/serial/8250/8250_fintek.c
+@@ -21,6 +21,7 @@
+ #define CHIP_ID_F81866 0x1010
+ #define CHIP_ID_F81966 0x0215
+ #define CHIP_ID_F81216AD 0x1602
++#define CHIP_ID_F81216E 0x1617
+ #define CHIP_ID_F81216H 0x0501
+ #define CHIP_ID_F81216 0x0802
+ #define VENDOR_ID1 0x23
+@@ -158,6 +159,7 @@ static int fintek_8250_check_id(struct fintek_8250 *pdata)
+ case CHIP_ID_F81866:
+ case CHIP_ID_F81966:
+ case CHIP_ID_F81216AD:
++ case CHIP_ID_F81216E:
+ case CHIP_ID_F81216H:
+ case CHIP_ID_F81216:
+ break;
+@@ -181,6 +183,7 @@ static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min,
+ return 0;
+
+ case CHIP_ID_F81216AD:
++ case CHIP_ID_F81216E:
+ case CHIP_ID_F81216H:
+ case CHIP_ID_F81216:
+ *min = F81216_LDN_LOW;
+@@ -250,6 +253,7 @@ static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)
+ break;
+
+ case CHIP_ID_F81216AD:
++ case CHIP_ID_F81216E:
+ case CHIP_ID_F81216H:
+ case CHIP_ID_F81216:
+ sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE,
+@@ -263,7 +267,8 @@ static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)
+ static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata)
+ {
+ switch (pdata->pid) {
+- case CHIP_ID_F81216H: /* 128Bytes FIFO */
++ case CHIP_ID_F81216E: /* 128Bytes FIFO */
++ case CHIP_ID_F81216H:
+ case CHIP_ID_F81966:
+ case CHIP_ID_F81866:
+ sio_write_mask_reg(pdata, FIFO_CTRL,
+@@ -297,6 +302,7 @@ static void fintek_8250_set_termios(struct uart_port *port,
+ goto exit;
+
+ switch (pdata->pid) {
++ case CHIP_ID_F81216E:
+ case CHIP_ID_F81216H:
+ reg = RS485;
+ break;
+@@ -346,6 +352,7 @@ static void fintek_8250_set_termios_handler(struct uart_8250_port *uart)
+ struct fintek_8250 *pdata = uart->port.private_data;
+
+ switch (pdata->pid) {
++ case CHIP_ID_F81216E:
+ case CHIP_ID_F81216H:
+ case CHIP_ID_F81966:
+ case CHIP_ID_F81866:
+@@ -438,6 +445,11 @@ static void fintek_8250_set_rs485_handler(struct uart_8250_port *uart)
+ uart->port.rs485_supported = fintek_8250_rs485_supported;
+ break;
+
++ case CHIP_ID_F81216E: /* F81216E does not support RS485 delays */
++ uart->port.rs485_config = fintek_8250_rs485_config;
++ uart->port.rs485_supported = fintek_8250_rs485_supported;
++ break;
++
+ default: /* No RS485 Auto direction functional */
+ break;
+ }
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index 4caecc3525bfd1..9ed62bc7cdd83a 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -766,12 +766,12 @@ static void omap_8250_shutdown(struct uart_port *port)
+ struct uart_8250_port *up = up_to_u8250p(port);
+ struct omap8250_priv *priv = port->private_data;
+
++ pm_runtime_get_sync(port->dev);
++
+ flush_work(&priv->qos_work);
+ if (up->dma)
+ omap_8250_rx_dma_flush(up);
+
+- pm_runtime_get_sync(port->dev);
+-
+ serial_out(up, UART_OMAP_WER, 0);
+ if (priv->habit & UART_HAS_EFR2)
+ serial_out(up, UART_OMAP_EFR2, 0x0);
+diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
+index 7a9924d9b294e9..f290fbe21d633e 100644
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -545,6 +545,8 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
+ SC16IS7XX_MCR_CLKSEL_BIT,
+ prescaler == 1 ? 0 : SC16IS7XX_MCR_CLKSEL_BIT);
+
++ mutex_lock(&one->efr_lock);
++
+ /* Open the LCR divisors for configuration */
+ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
+ SC16IS7XX_LCR_CONF_MODE_A);
+@@ -558,6 +560,8 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
+ /* Put LCR back to the normal mode */
+ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
+
++ mutex_unlock(&one->efr_lock);
++
+ return DIV_ROUND_CLOSEST((clk / prescaler) / 16, div);
+ }
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 493fc4742895f1..117abcf366d95f 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -3607,7 +3607,7 @@ static struct ctl_table tty_table[] = {
+ .data = &tty_ldisc_autoload,
+ .maxlen = sizeof(tty_ldisc_autoload),
+ .mode = 0644,
+- .proc_handler = proc_dointvec,
++ .proc_handler = proc_dointvec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ },
+diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
+index 3396e0388512c7..268189f01e15bc 100644
+--- a/drivers/ufs/host/ufs-exynos.c
++++ b/drivers/ufs/host/ufs-exynos.c
+@@ -1228,12 +1228,12 @@ static void exynos_ufs_dev_hw_reset(struct ufs_hba *hba)
+ hci_writel(ufs, 1 << 0, HCI_GPIO_OUT);
+ }
+
+-static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter)
++static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, enum uic_cmd_dme cmd)
+ {
+ struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+ struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
+
+- if (!enter) {
++ if (cmd == UIC_CMD_DME_HIBER_EXIT) {
+ if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
+ exynos_ufs_disable_auto_ctrl_hcc(ufs);
+ exynos_ufs_ungate_clks(ufs);
+@@ -1261,11 +1261,11 @@ static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter)
+ }
+ }
+
+-static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter)
++static void exynos_ufs_post_hibern8(struct ufs_hba *hba, enum uic_cmd_dme cmd)
+ {
+ struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+- if (!enter) {
++ if (cmd == UIC_CMD_DME_HIBER_EXIT) {
+ u32 cur_mode = 0;
+ u32 pwrmode;
+
+@@ -1284,7 +1284,7 @@ static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter)
+
+ if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB))
+ exynos_ufs_establish_connt(ufs);
+- } else {
++ } else if (cmd == UIC_CMD_DME_HIBER_ENTER) {
+ ufs->entry_hibern8_t = ktime_get();
+ exynos_ufs_gate_clks(ufs);
+ if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
+@@ -1371,15 +1371,15 @@ static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba,
+ }
+
+ static void exynos_ufs_hibern8_notify(struct ufs_hba *hba,
+- enum uic_cmd_dme enter,
++ enum uic_cmd_dme cmd,
+ enum ufs_notify_change_status notify)
+ {
+ switch ((u8)notify) {
+ case PRE_CHANGE:
+- exynos_ufs_pre_hibern8(hba, enter);
++ exynos_ufs_pre_hibern8(hba, cmd);
+ break;
+ case POST_CHANGE:
+- exynos_ufs_post_hibern8(hba, enter);
++ exynos_ufs_post_hibern8(hba, cmd);
+ break;
+ }
+ }
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 867000cdeb9653..9971076c31de64 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1196,11 +1196,14 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
+ * pending to be processed by the driver.
+ */
+ if (dep->trb_enqueue == dep->trb_dequeue) {
++ struct dwc3_request *req;
++
+ /*
+- * If there is any request remained in the started_list at
+- * this point, that means there is no TRB available.
++ * If there is any request remained in the started_list with
++ * active TRBs at this point, then there is no TRB available.
+ */
+- if (!list_empty(&dep->started_list))
++ req = next_request(&dep->started_list);
++ if (req && req->num_trbs)
+ return 0;
+
+ return DWC3_TRB_NUM - 1;
+@@ -1433,8 +1436,8 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
+ struct scatterlist *s;
+ int i;
+ unsigned int length = req->request.length;
+- unsigned int remaining = req->request.num_mapped_sgs
+- - req->num_queued_sgs;
++ unsigned int remaining = req->num_pending_sgs;
++ unsigned int num_queued_sgs = req->request.num_mapped_sgs - remaining;
+ unsigned int num_trbs = req->num_trbs;
+ bool needs_extra_trb = dwc3_needs_extra_trb(dep, req);
+
+@@ -1442,7 +1445,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
+ * If we resume preparing the request, then get the remaining length of
+ * the request and resume where we left off.
+ */
+- for_each_sg(req->request.sg, s, req->num_queued_sgs, i)
++ for_each_sg(req->request.sg, s, num_queued_sgs, i)
+ length -= sg_dma_len(s);
+
+ for_each_sg(sg, s, remaining, i) {
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index 0e151b54aae82a..9225c21d118453 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -2111,8 +2111,20 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+ memset(buf, 0, w_length);
+ buf[5] = 0x01;
+ switch (ctrl->bRequestType & USB_RECIP_MASK) {
++ /*
++ * The Microsoft CompatID OS Descriptor Spec(w_index = 0x4) and
++ * Extended Prop OS Desc Spec(w_index = 0x5) state that the
++ * HighByte of wValue is the InterfaceNumber and the LowByte is
++ * the PageNumber. This high/low byte ordering is incorrectly
++ * documented in the Spec. USB analyzer output on the below
++ * request packets show the high/low byte inverted i.e LowByte
++ * is the InterfaceNumber and the HighByte is the PageNumber.
++ * Since we dont support >64KB CompatID/ExtendedProp descriptors,
++ * PageNumber is set to 0. Hence verify that the HighByte is 0
++ * for below two cases.
++ */
+ case USB_RECIP_DEVICE:
+- if (w_index != 0x4 || (w_value & 0xff))
++ if (w_index != 0x4 || (w_value >> 8))
+ break;
+ buf[6] = w_index;
+ /* Number of ext compat interfaces */
+@@ -2128,9 +2140,9 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+ }
+ break;
+ case USB_RECIP_INTERFACE:
+- if (w_index != 0x5 || (w_value & 0xff))
++ if (w_index != 0x5 || (w_value >> 8))
+ break;
+- interface = w_value >> 8;
++ interface = w_value & 0xFF;
+ if (interface >= MAX_CONFIG_INTERFACES ||
+ !os_desc_cfg->interface[interface])
+ break;
+diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
+index d0e94e4c9fe274..11294f196ee335 100644
+--- a/drivers/usb/host/ehci-spear.c
++++ b/drivers/usb/host/ehci-spear.c
+@@ -105,7 +105,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
+ /* registers start at offset 0x0 */
+ hcd_to_ehci(hcd)->caps = hcd->regs;
+
+- clk_prepare_enable(sehci->clk);
++ retval = clk_prepare_enable(sehci->clk);
++ if (retval)
++ goto err_put_hcd;
+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (retval)
+ goto err_stop_ehci;
+@@ -130,8 +132,7 @@ static void spear_ehci_hcd_drv_remove(struct platform_device *pdev)
+
+ usb_remove_hcd(hcd);
+
+- if (sehci->clk)
+- clk_disable_unprepare(sehci->clk);
++ clk_disable_unprepare(sehci->clk);
+ usb_put_hcd(hcd);
+ }
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 6e38b6b480e098..258e64d6522c65 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -994,6 +994,13 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
+ unsigned int slot_id = ep->vdev->slot_id;
+ int err;
+
++ /*
++ * This is not going to work if the hardware is changing its dequeue
++ * pointers as we look at them. Completion handler will call us later.
++ */
++ if (ep->ep_state & SET_DEQ_PENDING)
++ return 0;
++
+ xhci = ep->xhci;
+
+ list_for_each_entry_safe(td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) {
+@@ -1354,7 +1361,6 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
+ struct xhci_ep_ctx *ep_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+ struct xhci_td *td, *tmp_td;
+- bool deferred = false;
+
+ ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
+ stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
+@@ -1455,8 +1461,6 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
+ xhci_dbg(ep->xhci, "%s: Giveback cancelled URB %p TD\n",
+ __func__, td->urb);
+ xhci_td_cleanup(ep->xhci, td, ep_ring, td->status);
+- } else if (td->cancel_status == TD_CLEARING_CACHE_DEFERRED) {
+- deferred = true;
+ } else {
+ xhci_dbg(ep->xhci, "%s: Keep cancelled URB %p TD as cancel_status is %d\n",
+ __func__, td->urb, td->cancel_status);
+@@ -1467,11 +1471,15 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
+ ep->queued_deq_seg = NULL;
+ ep->queued_deq_ptr = NULL;
+
+- if (deferred) {
+- /* We have more streams to clear */
++ /* Check for deferred or newly cancelled TDs */
++ if (!list_empty(&ep->cancelled_td_list)) {
+ xhci_dbg(ep->xhci, "%s: Pending TDs to clear, continuing with invalidation\n",
+ __func__);
+ xhci_invalidate_cancelled_tds(ep);
++ /* Try to restart the endpoint if all is done */
++ ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
++ /* Start giving back any TDs invalidated above */
++ xhci_giveback_invalidated_tds(ep);
+ } else {
+ /* Restart any rings with pending URBs */
+ xhci_dbg(ep->xhci, "%s: All TDs cleared, ring doorbell\n", __func__);
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index 6fb5140e29b9dd..225863321dc479 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -27,6 +27,8 @@ static struct usb_class_driver chaoskey_class;
+ static int chaoskey_rng_read(struct hwrng *rng, void *data,
+ size_t max, bool wait);
+
++static DEFINE_MUTEX(chaoskey_list_lock);
++
+ #define usb_dbg(usb_if, format, arg...) \
+ dev_dbg(&(usb_if)->dev, format, ## arg)
+
+@@ -233,6 +235,7 @@ static void chaoskey_disconnect(struct usb_interface *interface)
+ usb_deregister_dev(interface, &chaoskey_class);
+
+ usb_set_intfdata(interface, NULL);
++ mutex_lock(&chaoskey_list_lock);
+ mutex_lock(&dev->lock);
+
+ dev->present = false;
+@@ -244,6 +247,7 @@ static void chaoskey_disconnect(struct usb_interface *interface)
+ } else
+ mutex_unlock(&dev->lock);
+
++ mutex_unlock(&chaoskey_list_lock);
+ usb_dbg(interface, "disconnect done");
+ }
+
+@@ -251,6 +255,7 @@ static int chaoskey_open(struct inode *inode, struct file *file)
+ {
+ struct chaoskey *dev;
+ struct usb_interface *interface;
++ int rv = 0;
+
+ /* get the interface from minor number and driver information */
+ interface = usb_find_interface(&chaoskey_driver, iminor(inode));
+@@ -266,18 +271,23 @@ static int chaoskey_open(struct inode *inode, struct file *file)
+ }
+
+ file->private_data = dev;
++ mutex_lock(&chaoskey_list_lock);
+ mutex_lock(&dev->lock);
+- ++dev->open;
++ if (dev->present)
++ ++dev->open;
++ else
++ rv = -ENODEV;
+ mutex_unlock(&dev->lock);
++ mutex_unlock(&chaoskey_list_lock);
+
+- usb_dbg(interface, "open success");
+- return 0;
++ return rv;
+ }
+
+ static int chaoskey_release(struct inode *inode, struct file *file)
+ {
+ struct chaoskey *dev = file->private_data;
+ struct usb_interface *interface;
++ int rv = 0;
+
+ if (dev == NULL)
+ return -ENODEV;
+@@ -286,14 +296,15 @@ static int chaoskey_release(struct inode *inode, struct file *file)
+
+ usb_dbg(interface, "release");
+
++ mutex_lock(&chaoskey_list_lock);
+ mutex_lock(&dev->lock);
+
+ usb_dbg(interface, "open count at release is %d", dev->open);
+
+ if (dev->open <= 0) {
+ usb_dbg(interface, "invalid open count (%d)", dev->open);
+- mutex_unlock(&dev->lock);
+- return -ENODEV;
++ rv = -ENODEV;
++ goto bail;
+ }
+
+ --dev->open;
+@@ -302,13 +313,15 @@ static int chaoskey_release(struct inode *inode, struct file *file)
+ if (dev->open == 0) {
+ mutex_unlock(&dev->lock);
+ chaoskey_free(dev);
+- } else
+- mutex_unlock(&dev->lock);
+- } else
+- mutex_unlock(&dev->lock);
+-
++ goto destruction;
++ }
++ }
++bail:
++ mutex_unlock(&dev->lock);
++destruction:
++ mutex_unlock(&chaoskey_list_lock);
+ usb_dbg(interface, "release success");
+- return 0;
++ return rv;
+ }
+
+ static void chaos_read_callback(struct urb *urb)
+diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
+index 1e3df27bab58fd..4fae04094021e3 100644
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -277,28 +277,45 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer,
+ struct iowarrior *dev;
+ int read_idx;
+ int offset;
++ int retval;
+
+ dev = file->private_data;
+
++ if (file->f_flags & O_NONBLOCK) {
++ retval = mutex_trylock(&dev->mutex);
++ if (!retval)
++ return -EAGAIN;
++ } else {
++ retval = mutex_lock_interruptible(&dev->mutex);
++ if (retval)
++ return -ERESTARTSYS;
++ }
++
+ /* verify that the device wasn't unplugged */
+- if (!dev || !dev->present)
+- return -ENODEV;
++ if (!dev->present) {
++ retval = -ENODEV;
++ goto exit;
++ }
+
+ dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
+ dev->minor, count);
+
+ /* read count must be packet size (+ time stamp) */
+ if ((count != dev->report_size)
+- && (count != (dev->report_size + 1)))
+- return -EINVAL;
++ && (count != (dev->report_size + 1))) {
++ retval = -EINVAL;
++ goto exit;
++ }
+
+ /* repeat until no buffer overrun in callback handler occur */
+ do {
+ atomic_set(&dev->overflow_flag, 0);
+ if ((read_idx = read_index(dev)) == -1) {
+ /* queue empty */
+- if (file->f_flags & O_NONBLOCK)
+- return -EAGAIN;
++ if (file->f_flags & O_NONBLOCK) {
++ retval = -EAGAIN;
++ goto exit;
++ }
+ else {
+ //next line will return when there is either new data, or the device is unplugged
+ int r = wait_event_interruptible(dev->read_wait,
+@@ -309,28 +326,37 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer,
+ -1));
+ if (r) {
+ //we were interrupted by a signal
+- return -ERESTART;
++ retval = -ERESTART;
++ goto exit;
+ }
+ if (!dev->present) {
+ //The device was unplugged
+- return -ENODEV;
++ retval = -ENODEV;
++ goto exit;
+ }
+ if (read_idx == -1) {
+ // Can this happen ???
+- return 0;
++ retval = 0;
++ goto exit;
+ }
+ }
+ }
+
+ offset = read_idx * (dev->report_size + 1);
+ if (copy_to_user(buffer, dev->read_queue + offset, count)) {
+- return -EFAULT;
++ retval = -EFAULT;
++ goto exit;
+ }
+ } while (atomic_read(&dev->overflow_flag));
+
+ read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
+ atomic_set(&dev->read_idx, read_idx);
++ mutex_unlock(&dev->mutex);
+ return count;
++
++exit:
++ mutex_unlock(&dev->mutex);
++ return retval;
+ }
+
+ /*
+@@ -886,7 +912,6 @@ static int iowarrior_probe(struct usb_interface *interface,
+ static void iowarrior_disconnect(struct usb_interface *interface)
+ {
+ struct iowarrior *dev = usb_get_intfdata(interface);
+- int minor = dev->minor;
+
+ usb_deregister_dev(interface, &iowarrior_class);
+
+@@ -910,9 +935,6 @@ static void iowarrior_disconnect(struct usb_interface *interface)
+ mutex_unlock(&dev->mutex);
+ iowarrior_delete(dev);
+ }
+-
+- dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
+- minor - IOWARRIOR_MINOR_BASE);
+ }
+
+ /* usb specific object needed to register this driver with the usb subsystem */
+diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
+index c313cd41f7a5a5..0eed614ac12739 100644
+--- a/drivers/usb/misc/yurex.c
++++ b/drivers/usb/misc/yurex.c
+@@ -441,7 +441,10 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
+ if (count == 0)
+ goto error;
+
+- mutex_lock(&dev->io_mutex);
++ retval = mutex_lock_interruptible(&dev->io_mutex);
++ if (retval < 0)
++ return -EINTR;
++
+ if (dev->disconnected) { /* already disconnected */
+ mutex_unlock(&dev->io_mutex);
+ retval = -ENODEV;
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index 051c6da7cf6d74..f175cb2c3e7bd2 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1170,12 +1170,19 @@ struct free_record {
+ */
+ void musb_ep_restart(struct musb *musb, struct musb_request *req)
+ {
++ u16 csr;
++ void __iomem *epio = req->ep->hw_ep->regs;
++
+ trace_musb_req_start(req);
+ musb_ep_select(musb->mregs, req->epnum);
+- if (req->tx)
++ if (req->tx) {
+ txstate(musb, req);
+- else
+- rxstate(musb, req);
++ } else {
++ csr = musb_readw(epio, MUSB_RXCSR);
++ csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_P_WZC_BITS;
++ musb_writew(epio, MUSB_RXCSR, csr);
++ musb_writew(epio, MUSB_RXCSR, csr);
++ }
+ }
+
+ static int musb_ep_restart_resume_work(struct musb *musb, void *data)
+diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
+index 64bdba7ea9938a..afb7192adc8e68 100644
+--- a/drivers/usb/typec/class.c
++++ b/drivers/usb/typec/class.c
+@@ -2147,14 +2147,16 @@ void typec_port_register_altmodes(struct typec_port *port,
+ const struct typec_altmode_ops *ops, void *drvdata,
+ struct typec_altmode **altmodes, size_t n)
+ {
+- struct fwnode_handle *altmodes_node, *child;
++ struct fwnode_handle *child;
+ struct typec_altmode_desc desc;
+ struct typec_altmode *alt;
+ size_t index = 0;
+ u32 svid, vdo;
+ int ret;
+
+- altmodes_node = device_get_named_child_node(&port->dev, "altmodes");
++ struct fwnode_handle *altmodes_node __free(fwnode_handle) =
++ device_get_named_child_node(&port->dev, "altmodes");
++
+ if (!altmodes_node)
+ return; /* No altmodes specified */
+
+diff --git a/drivers/usb/typec/tcpm/wcove.c b/drivers/usb/typec/tcpm/wcove.c
+index 87d4abde0ea279..e08244f555f039 100644
+--- a/drivers/usb/typec/tcpm/wcove.c
++++ b/drivers/usb/typec/tcpm/wcove.c
+@@ -621,10 +621,6 @@ static int wcove_typec_probe(struct platform_device *pdev)
+ if (irq < 0)
+ return irq;
+
+- irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr, irq);
+- if (irq < 0)
+- return irq;
+-
+ ret = guid_parse(WCOVE_DSM_UUID, &wcove->guid);
+ if (ret)
+ return ret;
+diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
+index 59fa9f3d5ec873..aa4ab4c847fdcc 100644
+--- a/drivers/vdpa/mlx5/core/mr.c
++++ b/drivers/vdpa/mlx5/core/mr.c
+@@ -227,7 +227,6 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
+ unsigned long lgcd = 0;
+ int log_entity_size;
+ unsigned long size;
+- u64 start = 0;
+ int err;
+ struct page *pg;
+ unsigned int nsg;
+@@ -238,10 +237,9 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
+ struct device *dma = mvdev->vdev.dma_dev;
+
+ for (map = vhost_iotlb_itree_first(iotlb, mr->start, mr->end - 1);
+- map; map = vhost_iotlb_itree_next(map, start, mr->end - 1)) {
++ map; map = vhost_iotlb_itree_next(map, mr->start, mr->end - 1)) {
+ size = maplen(map, mr);
+ lgcd = gcd(lgcd, size);
+- start += size;
+ }
+ log_entity_size = ilog2(lgcd);
+
+diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
+index 7e2e62ab0869cf..a2ad4f7c716bf3 100644
+--- a/drivers/vfio/pci/vfio_pci_config.c
++++ b/drivers/vfio/pci/vfio_pci_config.c
+@@ -313,6 +313,10 @@ static int vfio_virt_config_read(struct vfio_pci_core_device *vdev, int pos,
+ return count;
+ }
+
++static struct perm_bits direct_ro_perms = {
++ .readfn = vfio_direct_config_read,
++};
++
+ /* Default capability regions to read-only, no-virtualization */
+ static struct perm_bits cap_perms[PCI_CAP_ID_MAX + 1] = {
+ [0 ... PCI_CAP_ID_MAX] = { .readfn = vfio_direct_config_read }
+@@ -1897,9 +1901,17 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_core_device *vdev, char __user
+ cap_start = *ppos;
+ } else {
+ if (*ppos >= PCI_CFG_SPACE_SIZE) {
+- WARN_ON(cap_id > PCI_EXT_CAP_ID_MAX);
++ /*
++ * We can get a cap_id that exceeds PCI_EXT_CAP_ID_MAX
++ * if we're hiding an unknown capability at the start
++ * of the extended capability list. Use default, ro
++ * access, which will virtualize the id and next values.
++ */
++ if (cap_id > PCI_EXT_CAP_ID_MAX)
++ perm = &direct_ro_perms;
++ else
++ perm = &ecap_perms[cap_id];
+
+- perm = &ecap_perms[cap_id];
+ cap_start = vfio_find_cap_start(vdev, *ppos);
+ } else {
+ WARN_ON(cap_id > PCI_CAP_ID_MAX);
+diff --git a/drivers/video/fbdev/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c
+index 08a4943dc54184..d0ee5fec647adb 100644
+--- a/drivers/video/fbdev/sh7760fb.c
++++ b/drivers/video/fbdev/sh7760fb.c
+@@ -409,12 +409,11 @@ static int sh7760fb_alloc_mem(struct fb_info *info)
+ vram = PAGE_SIZE;
+
+ fbmem = dma_alloc_coherent(info->device, vram, &par->fbdma, GFP_KERNEL);
+-
+ if (!fbmem)
+ return -ENOMEM;
+
+ if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) {
+- sh7760fb_free_mem(info);
++ dma_free_coherent(info->device, vram, fbmem, par->fbdma);
+ dev_err(info->device, "kernel gave me memory at 0x%08lx, which is"
+ "unusable for the LCDC\n", (unsigned long)par->fbdma);
+ return -ENOMEM;
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 1a9ded0cddcb0f..25164d56c9d995 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -313,7 +313,7 @@ int xenbus_dev_probe(struct device *_dev)
+ if (err) {
+ dev_warn(&dev->dev, "watch_otherend on %s failed.\n",
+ dev->nodename);
+- return err;
++ goto fail_remove;
+ }
+
+ dev->spurious_threshold = 1;
+@@ -322,6 +322,12 @@ int xenbus_dev_probe(struct device *_dev)
+ dev->nodename);
+
+ return 0;
++fail_remove:
++ if (drv->remove) {
++ down(&dev->reclaim_sem);
++ drv->remove(dev);
++ up(&dev->reclaim_sem);
++ }
+ fail_put:
+ module_put(drv->driver.owner);
+ fail:
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index 2eb4e03080ac9b..25c902e7556d57 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -617,10 +617,16 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
+ atomic_inc(&cow->refs);
+ rcu_assign_pointer(root->node, cow);
+
+- btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
+- parent_start, last_ref);
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
++ parent_start, last_ref);
+ free_extent_buffer(buf);
+ add_root_to_dirty_list(root);
++ if (ret < 0) {
++ btrfs_tree_unlock(cow);
++ free_extent_buffer(cow);
++ btrfs_abort_transaction(trans, ret);
++ return ret;
++ }
+ } else {
+ WARN_ON(trans->transid != btrfs_header_generation(parent));
+ ret = btrfs_tree_mod_log_insert_key(parent, parent_slot,
+@@ -645,8 +651,14 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
+ return ret;
+ }
+ }
+- btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
+- parent_start, last_ref);
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
++ parent_start, last_ref);
++ if (ret < 0) {
++ btrfs_tree_unlock(cow);
++ free_extent_buffer(cow);
++ btrfs_abort_transaction(trans, ret);
++ return ret;
++ }
+ }
+ if (unlock_orig)
+ btrfs_tree_unlock(buf);
+@@ -1121,9 +1133,13 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
+ free_extent_buffer(mid);
+
+ root_sub_used(root, mid->len);
+- btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
+ /* once for the root ptr */
+ free_extent_buffer_stale(mid);
++ if (ret < 0) {
++ btrfs_abort_transaction(trans, ret);
++ goto out;
++ }
+ return 0;
+ }
+ if (btrfs_header_nritems(mid) >
+@@ -1191,10 +1207,14 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
+ goto out;
+ }
+ root_sub_used(root, right->len);
+- btrfs_free_tree_block(trans, btrfs_root_id(root), right,
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), right,
+ 0, 1);
+ free_extent_buffer_stale(right);
+ right = NULL;
++ if (ret < 0) {
++ btrfs_abort_transaction(trans, ret);
++ goto out;
++ }
+ } else {
+ struct btrfs_disk_key right_key;
+ btrfs_node_key(right, &right_key, 0);
+@@ -1249,9 +1269,13 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
+ goto out;
+ }
+ root_sub_used(root, mid->len);
+- btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
+ free_extent_buffer_stale(mid);
+ mid = NULL;
++ if (ret < 0) {
++ btrfs_abort_transaction(trans, ret);
++ goto out;
++ }
+ } else {
+ /* update the parent key to reflect our changes */
+ struct btrfs_disk_key mid_key;
+@@ -2133,7 +2157,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ const struct btrfs_key *key, struct btrfs_path *p,
+ int ins_len, int cow)
+ {
+- struct btrfs_fs_info *fs_info = root->fs_info;
++ struct btrfs_fs_info *fs_info;
+ struct extent_buffer *b;
+ int slot;
+ int ret;
+@@ -2146,6 +2170,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ int min_write_lock_level;
+ int prev_cmp;
+
++ if (!root)
++ return -EINVAL;
++
++ fs_info = root->fs_info;
+ might_sleep();
+
+ lowest_level = p->lowest_level;
+@@ -3022,7 +3050,11 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
+ old = root->node;
+ ret = btrfs_tree_mod_log_insert_root(root->node, c, false);
+ if (ret < 0) {
+- btrfs_free_tree_block(trans, btrfs_root_id(root), c, 0, 1);
++ int ret2;
++
++ ret2 = btrfs_free_tree_block(trans, btrfs_root_id(root), c, 0, 1);
++ if (ret2 < 0)
++ btrfs_abort_transaction(trans, ret2);
+ btrfs_tree_unlock(c);
+ free_extent_buffer(c);
+ return ret;
+@@ -4587,9 +4619,12 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
+ root_sub_used(root, leaf->len);
+
+ atomic_inc(&leaf->refs);
+- btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1);
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1);
+ free_extent_buffer_stale(leaf);
+- return 0;
++ if (ret < 0)
++ btrfs_abort_transaction(trans, ret);
++
++ return ret;
+ }
+ /*
+ * delete the item at the leaf level in path. If that empties
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index b3680e1c7054c4..7aa8c1a2161b8f 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -2401,7 +2401,7 @@ int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset,
+ goto out;
+
+ ret = check_delayed_ref(root, path, objectid, offset, bytenr);
+- } while (ret == -EAGAIN);
++ } while (ret == -EAGAIN && !path->nowait);
+
+ out:
+ btrfs_release_path(path);
+@@ -3290,10 +3290,10 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
+ return 0;
+ }
+
+-void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+- u64 root_id,
+- struct extent_buffer *buf,
+- u64 parent, int last_ref)
++int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
++ u64 root_id,
++ struct extent_buffer *buf,
++ u64 parent, int last_ref)
+ {
+ struct btrfs_fs_info *fs_info = trans->fs_info;
+ struct btrfs_ref generic_ref = { 0 };
+@@ -3307,7 +3307,8 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ if (root_id != BTRFS_TREE_LOG_OBJECTID) {
+ btrfs_ref_tree_mod(fs_info, &generic_ref);
+ ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL);
+- BUG_ON(ret); /* -ENOMEM */
++ if (ret < 0)
++ return ret;
+ }
+
+ if (last_ref && btrfs_header_generation(buf) == trans->transid) {
+@@ -3371,6 +3372,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ */
+ clear_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags);
+ }
++ return 0;
+ }
+
+ /* Can return -ENOMEM */
+@@ -5168,7 +5170,6 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
+ eb->start, level, 1,
+ &wc->refs[level],
+ &wc->flags[level]);
+- BUG_ON(ret == -ENOMEM);
+ if (ret)
+ return ret;
+ if (unlikely(wc->refs[level] == 0)) {
+@@ -5474,7 +5475,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
+ struct walk_control *wc)
+ {
+ struct btrfs_fs_info *fs_info = root->fs_info;
+- int ret;
++ int ret = 0;
+ int level = wc->level;
+ struct extent_buffer *eb = path->nodes[level];
+ u64 parent = 0;
+@@ -5565,12 +5566,14 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
+ goto owner_mismatch;
+ }
+
+- btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent,
+- wc->refs[level] == 1);
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent,
++ wc->refs[level] == 1);
++ if (ret < 0)
++ btrfs_abort_transaction(trans, ret);
+ out:
+ wc->refs[level] = 0;
+ wc->flags[level] = 0;
+- return 0;
++ return ret;
+
+ owner_mismatch:
+ btrfs_err_rl(fs_info, "unexpected tree owner, have %llu expect %llu",
+diff --git a/fs/btrfs/extent-tree.h b/fs/btrfs/extent-tree.h
+index 88c249c37516a1..ef1c1c99294ebd 100644
+--- a/fs/btrfs/extent-tree.h
++++ b/fs/btrfs/extent-tree.h
+@@ -114,10 +114,10 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
+ int level, u64 hint,
+ u64 empty_size,
+ enum btrfs_lock_nesting nest);
+-void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+- u64 root_id,
+- struct extent_buffer *buf,
+- u64 parent, int last_ref);
++int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
++ u64 root_id,
++ struct extent_buffer *buf,
++ u64 parent, int last_ref);
+ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, u64 owner,
+ u64 offset, u64 ram_bytes,
+diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
+index 7b598b070700e7..a0d8160b537572 100644
+--- a/fs/btrfs/free-space-tree.c
++++ b/fs/btrfs/free-space-tree.c
+@@ -1289,10 +1289,14 @@ int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info)
+ btrfs_tree_lock(free_space_root->node);
+ btrfs_clear_buffer_dirty(trans, free_space_root->node);
+ btrfs_tree_unlock(free_space_root->node);
+- btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
+- free_space_root->node, 0, 1);
+-
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
++ free_space_root->node, 0, 1);
+ btrfs_put_root(free_space_root);
++ if (ret < 0) {
++ btrfs_abort_transaction(trans, ret);
++ btrfs_end_transaction(trans);
++ return ret;
++ }
+
+ return btrfs_commit_transaction(trans);
+
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 5f0c9c3f3bbf09..ae6806bc392916 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -707,6 +707,8 @@ static noinline int create_subvol(struct mnt_idmap *idmap,
+ ret = btrfs_insert_root(trans, fs_info->tree_root, &key,
+ root_item);
+ if (ret) {
++ int ret2;
++
+ /*
+ * Since we don't abort the transaction in this case, free the
+ * tree block so that we don't leak space and leave the
+@@ -717,7 +719,9 @@ static noinline int create_subvol(struct mnt_idmap *idmap,
+ btrfs_tree_lock(leaf);
+ btrfs_clear_buffer_dirty(trans, leaf);
+ btrfs_tree_unlock(leaf);
+- btrfs_free_tree_block(trans, objectid, leaf, 0, 1);
++ ret2 = btrfs_free_tree_block(trans, objectid, leaf, 0, 1);
++ if (ret2 < 0)
++ btrfs_abort_transaction(trans, ret2);
+ free_extent_buffer(leaf);
+ goto out;
+ }
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 74b82390fe8470..1b9f4f16d12404 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1320,9 +1320,11 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
+ btrfs_tree_lock(quota_root->node);
+ btrfs_clear_buffer_dirty(trans, quota_root->node);
+ btrfs_tree_unlock(quota_root->node);
+- btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
+- quota_root->node, 0, 1);
++ ret = btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
++ quota_root->node, 0, 1);
+
++ if (ret < 0)
++ btrfs_abort_transaction(trans, ret);
+
+ out:
+ btrfs_put_root(quota_root);
+diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c
+index 1ea5bfb8876e41..28ac7995716e04 100644
+--- a/fs/btrfs/ref-verify.c
++++ b/fs/btrfs/ref-verify.c
+@@ -849,6 +849,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info,
+ "dropping a ref for a root that doesn't have a ref on the block");
+ dump_block_entry(fs_info, be);
+ dump_ref_action(fs_info, ra);
++ rb_erase(&ref->node, &be->refs);
+ kfree(ref);
+ kfree(ra);
+ goto out_unlock;
+diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c
+index 2185e2908dba89..d1a0264b08a6c1 100644
+--- a/fs/cachefiles/ondemand.c
++++ b/fs/cachefiles/ondemand.c
+@@ -78,8 +78,10 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
+
+ trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
+ ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
+- if (!ret)
++ if (!ret) {
+ ret = len;
++ kiocb->ki_pos += ret;
++ }
+
+ return ret;
+ }
+diff --git a/fs/ceph/super.c b/fs/ceph/super.c
+index ec51e398562c6f..4f51a2e74d074b 100644
+--- a/fs/ceph/super.c
++++ b/fs/ceph/super.c
+@@ -281,7 +281,9 @@ static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end,
+ size_t len;
+ struct ceph_fsid fsid;
+ struct ceph_parse_opts_ctx *pctx = fc->fs_private;
++ struct ceph_options *opts = pctx->copts;
+ struct ceph_mount_options *fsopt = pctx->opts;
++ const char *name_start = dev_name;
+ char *fsid_start, *fs_name_start;
+
+ if (*dev_name_end != '=') {
+@@ -292,8 +294,14 @@ static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end,
+ fsid_start = strchr(dev_name, '@');
+ if (!fsid_start)
+ return invalfc(fc, "missing cluster fsid");
+- ++fsid_start; /* start of cluster fsid */
++ len = fsid_start - name_start;
++ kfree(opts->name);
++ opts->name = kstrndup(name_start, len, GFP_KERNEL);
++ if (!opts->name)
++ return -ENOMEM;
++ dout("using %s entity name", opts->name);
+
++ ++fsid_start; /* start of cluster fsid */
+ fs_name_start = strchr(fsid_start, '.');
+ if (!fs_name_start)
+ return invalfc(fc, "missing file system name");
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index 6bd435a565f614..76566c2cbf63eb 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -234,7 +234,7 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
+ unsigned int amortizedshift;
+ erofs_off_t pos;
+
+- if (lcn >= totalidx)
++ if (lcn >= totalidx || vi->z_logical_clusterbits > 14)
+ return -EINVAL;
+
+ m->lcn = lcn;
+@@ -409,7 +409,7 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
+ u64 lcn = m->lcn, headlcn = map->m_la >> lclusterbits;
+ int err;
+
+- do {
++ while (1) {
+ /* handle the last EOF pcluster (no next HEAD lcluster) */
+ if ((lcn << lclusterbits) >= inode->i_size) {
+ map->m_llen = inode->i_size - map->m_la;
+@@ -421,14 +421,16 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
+ return err;
+
+ if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
+- DBG_BUGON(!m->delta[1] &&
+- m->clusterofs != 1 << lclusterbits);
++ /* work around invalid d1 generated by pre-1.0 mkfs */
++ if (unlikely(!m->delta[1])) {
++ m->delta[1] = 1;
++ DBG_BUGON(1);
++ }
+ } else if (m->type == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
+ m->type == Z_EROFS_LCLUSTER_TYPE_HEAD1 ||
+ m->type == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
+- /* go on until the next HEAD lcluster */
+ if (lcn != headlcn)
+- break;
++ break; /* ends at the next HEAD lcluster */
+ m->delta[1] = 1;
+ } else {
+ erofs_err(inode->i_sb, "unknown type %u @ lcn %llu of nid %llu",
+@@ -437,8 +439,7 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
+ return -EOPNOTSUPP;
+ }
+ lcn += m->delta[1];
+- } while (m->delta[1]);
+-
++ }
+ map->m_llen = (lcn << lclusterbits) + m->clusterofs - map->m_la;
+ return 0;
+ }
+diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
+index 95c51b025b9176..f340e96b499f1c 100644
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -377,6 +377,7 @@ static int exfat_find_empty_entry(struct inode *inode,
+ if (ei->start_clu == EXFAT_EOF_CLUSTER) {
+ ei->start_clu = clu.dir;
+ p_dir->dir = clu.dir;
++ hint_femp.eidx = 0;
+ }
+
+ /* append to the FAT chain */
+diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
+index 79b20d6ae39ec4..396474e9e2bffe 100644
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -545,7 +545,8 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group,
+ trace_ext4_read_block_bitmap_load(sb, block_group, ignore_locked);
+ ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO |
+ (ignore_locked ? REQ_RAHEAD : 0),
+- ext4_end_bitmap_read);
++ ext4_end_bitmap_read,
++ ext4_simulate_fail(sb, EXT4_SIM_BBITMAP_EIO));
+ return bh;
+ verify:
+ err = ext4_validate_block_bitmap(sb, desc, block_group, bh);
+@@ -569,7 +570,6 @@ int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
+ if (!desc)
+ return -EFSCORRUPTED;
+ wait_on_buffer(bh);
+- ext4_simulate_fail_bh(sb, bh, EXT4_SIM_BBITMAP_EIO);
+ if (!buffer_uptodate(bh)) {
+ ext4_error_err(sb, EIO, "Cannot read block bitmap - "
+ "block_group = %u, block_bitmap = %llu",
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 7bbf0b9bdff239..3db01b933c3e8b 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1849,14 +1849,6 @@ static inline bool ext4_simulate_fail(struct super_block *sb,
+ return false;
+ }
+
+-static inline void ext4_simulate_fail_bh(struct super_block *sb,
+- struct buffer_head *bh,
+- unsigned long code)
+-{
+- if (!IS_ERR(bh) && ext4_simulate_fail(sb, code))
+- clear_buffer_uptodate(bh);
+-}
+-
+ /*
+ * Error number codes for s_{first,last}_error_errno
+ *
+@@ -3072,9 +3064,9 @@ extern struct buffer_head *ext4_sb_bread(struct super_block *sb,
+ extern struct buffer_head *ext4_sb_bread_unmovable(struct super_block *sb,
+ sector_t block);
+ extern void ext4_read_bh_nowait(struct buffer_head *bh, blk_opf_t op_flags,
+- bh_end_io_t *end_io);
++ bh_end_io_t *end_io, bool simu_fail);
+ extern int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags,
+- bh_end_io_t *end_io);
++ bh_end_io_t *end_io, bool simu_fail);
+ extern int ext4_read_bh_lock(struct buffer_head *bh, blk_opf_t op_flags, bool wait);
+ extern void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block);
+ extern int ext4_seq_options_show(struct seq_file *seq, void *offset);
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 1c059ac1c1ef27..5ea75af6ca2239 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -564,7 +564,7 @@ __read_extent_tree_block(const char *function, unsigned int line,
+
+ if (!bh_uptodate_or_lock(bh)) {
+ trace_ext4_ext_load_extent(inode, pblk, _RET_IP_);
+- err = ext4_read_bh(bh, 0, NULL);
++ err = ext4_read_bh(bh, 0, NULL, false);
+ if (err < 0)
+ goto errout;
+ }
+diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c
+index cdf9bfe10137ff..53a05b8292f033 100644
+--- a/fs/ext4/fsmap.c
++++ b/fs/ext4/fsmap.c
+@@ -185,6 +185,56 @@ static inline ext4_fsblk_t ext4_fsmap_next_pblk(struct ext4_fsmap *fmr)
+ return fmr->fmr_physical + fmr->fmr_length;
+ }
+
++static int ext4_getfsmap_meta_helper(struct super_block *sb,
++ ext4_group_t agno, ext4_grpblk_t start,
++ ext4_grpblk_t len, void *priv)
++{
++ struct ext4_getfsmap_info *info = priv;
++ struct ext4_fsmap *p;
++ struct ext4_fsmap *tmp;
++ struct ext4_sb_info *sbi = EXT4_SB(sb);
++ ext4_fsblk_t fsb, fs_start, fs_end;
++ int error;
++
++ fs_start = fsb = (EXT4_C2B(sbi, start) +
++ ext4_group_first_block_no(sb, agno));
++ fs_end = fs_start + EXT4_C2B(sbi, len);
++
++ /* Return relevant extents from the meta_list */
++ list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) {
++ if (p->fmr_physical < info->gfi_next_fsblk) {
++ list_del(&p->fmr_list);
++ kfree(p);
++ continue;
++ }
++ if (p->fmr_physical <= fs_start ||
++ p->fmr_physical + p->fmr_length <= fs_end) {
++ /* Emit the retained free extent record if present */
++ if (info->gfi_lastfree.fmr_owner) {
++ error = ext4_getfsmap_helper(sb, info,
++ &info->gfi_lastfree);
++ if (error)
++ return error;
++ info->gfi_lastfree.fmr_owner = 0;
++ }
++ error = ext4_getfsmap_helper(sb, info, p);
++ if (error)
++ return error;
++ fsb = p->fmr_physical + p->fmr_length;
++ if (info->gfi_next_fsblk < fsb)
++ info->gfi_next_fsblk = fsb;
++ list_del(&p->fmr_list);
++ kfree(p);
++ continue;
++ }
++ }
++ if (info->gfi_next_fsblk < fsb)
++ info->gfi_next_fsblk = fsb;
++
++ return 0;
++}
++
++
+ /* Transform a blockgroup's free record into a fsmap */
+ static int ext4_getfsmap_datadev_helper(struct super_block *sb,
+ ext4_group_t agno, ext4_grpblk_t start,
+@@ -539,6 +589,7 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
+ error = ext4_mballoc_query_range(sb, info->gfi_agno,
+ EXT4_B2C(sbi, info->gfi_low.fmr_physical),
+ EXT4_B2C(sbi, info->gfi_high.fmr_physical),
++ ext4_getfsmap_meta_helper,
+ ext4_getfsmap_datadev_helper, info);
+ if (error)
+ goto err;
+@@ -560,7 +611,8 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
+
+ /* Report any gaps at the end of the bg */
+ info->gfi_last = true;
+- error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster, 0, info);
++ error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1,
++ 0, info);
+ if (error)
+ goto err;
+
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index 1a1e2214c581f3..d4d0ad689d3c1c 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -194,8 +194,9 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
+ * submit the buffer_head for reading
+ */
+ trace_ext4_load_inode_bitmap(sb, block_group);
+- ext4_read_bh(bh, REQ_META | REQ_PRIO, ext4_end_bitmap_read);
+- ext4_simulate_fail_bh(sb, bh, EXT4_SIM_IBITMAP_EIO);
++ ext4_read_bh(bh, REQ_META | REQ_PRIO,
++ ext4_end_bitmap_read,
++ ext4_simulate_fail(sb, EXT4_SIM_IBITMAP_EIO));
+ if (!buffer_uptodate(bh)) {
+ put_bh(bh);
+ ext4_error_err(sb, EIO, "Cannot read inode bitmap - "
+diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
+index a9f3716119d372..f2c495b745f1e4 100644
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -170,7 +170,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
+ }
+
+ if (!bh_uptodate_or_lock(bh)) {
+- if (ext4_read_bh(bh, 0, NULL) < 0) {
++ if (ext4_read_bh(bh, 0, NULL, false) < 0) {
+ put_bh(bh);
+ goto failure;
+ }
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 14f7098bcefe1c..18ec9106c5b09f 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4508,10 +4508,10 @@ static int __ext4_get_inode_loc(struct super_block *sb, unsigned long ino,
+ * Read the block from disk.
+ */
+ trace_ext4_load_inode(sb, ino);
+- ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO, NULL);
++ ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO, NULL,
++ ext4_simulate_fail(sb, EXT4_SIM_INODE_EIO));
+ blk_finish_plug(&plug);
+ wait_on_buffer(bh);
+- ext4_simulate_fail_bh(sb, bh, EXT4_SIM_INODE_EIO);
+ if (!buffer_uptodate(bh)) {
+ if (ret_block)
+ *ret_block = block;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 87ba7f58216f70..8a9f8c95c6f1eb 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -7155,13 +7155,14 @@ int
+ ext4_mballoc_query_range(
+ struct super_block *sb,
+ ext4_group_t group,
+- ext4_grpblk_t start,
++ ext4_grpblk_t first,
+ ext4_grpblk_t end,
++ ext4_mballoc_query_range_fn meta_formatter,
+ ext4_mballoc_query_range_fn formatter,
+ void *priv)
+ {
+ void *bitmap;
+- ext4_grpblk_t next;
++ ext4_grpblk_t start, next;
+ struct ext4_buddy e4b;
+ int error;
+
+@@ -7172,10 +7173,19 @@ ext4_mballoc_query_range(
+
+ ext4_lock_group(sb, group);
+
+- start = max(e4b.bd_info->bb_first_free, start);
++ start = max(e4b.bd_info->bb_first_free, first);
+ if (end >= EXT4_CLUSTERS_PER_GROUP(sb))
+ end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
+-
++ if (meta_formatter && start != first) {
++ if (start > end)
++ start = end;
++ ext4_unlock_group(sb, group);
++ error = meta_formatter(sb, group, first, start - first,
++ priv);
++ if (error)
++ goto out_unload;
++ ext4_lock_group(sb, group);
++ }
+ while (start <= end) {
+ start = mb_find_next_zero_bit(bitmap, end + 1, start);
+ if (start > end)
+diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
+index 498af2abc5d885..dd16050022f524 100644
+--- a/fs/ext4/mballoc.h
++++ b/fs/ext4/mballoc.h
+@@ -260,6 +260,7 @@ ext4_mballoc_query_range(
+ ext4_group_t agno,
+ ext4_grpblk_t start,
+ ext4_grpblk_t end,
++ ext4_mballoc_query_range_fn meta_formatter,
+ ext4_mballoc_query_range_fn formatter,
+ void *priv);
+
+diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
+index bd946d0c71b700..d64c04ed061ae9 100644
+--- a/fs/ext4/mmp.c
++++ b/fs/ext4/mmp.c
+@@ -94,7 +94,7 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh,
+ }
+
+ lock_buffer(*bh);
+- ret = ext4_read_bh(*bh, REQ_META | REQ_PRIO, NULL);
++ ret = ext4_read_bh(*bh, REQ_META | REQ_PRIO, NULL, false);
+ if (ret)
+ goto warn_exit;
+
+diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
+index 0bfd5ff103aa44..5e6b07b3496006 100644
+--- a/fs/ext4/move_extent.c
++++ b/fs/ext4/move_extent.c
+@@ -165,15 +165,16 @@ mext_folio_double_lock(struct inode *inode1, struct inode *inode2,
+ return 0;
+ }
+
+-/* Force page buffers uptodate w/o dropping page's lock */
+-static int
+-mext_page_mkuptodate(struct folio *folio, unsigned from, unsigned to)
++/* Force folio buffers uptodate w/o dropping folio's lock */
++static int mext_page_mkuptodate(struct folio *folio, size_t from, size_t to)
+ {
+ struct inode *inode = folio->mapping->host;
+ sector_t block;
+- struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
++ struct buffer_head *bh, *head;
+ unsigned int blocksize, block_start, block_end;
+- int i, err, nr = 0, partial = 0;
++ int nr = 0;
++ bool partial = false;
++
+ BUG_ON(!folio_test_locked(folio));
+ BUG_ON(folio_test_writeback(folio));
+
+@@ -193,38 +194,44 @@ mext_page_mkuptodate(struct folio *folio, unsigned from, unsigned to)
+ block_end = block_start + blocksize;
+ if (block_end <= from || block_start >= to) {
+ if (!buffer_uptodate(bh))
+- partial = 1;
++ partial = true;
+ continue;
+ }
+ if (buffer_uptodate(bh))
+ continue;
+ if (!buffer_mapped(bh)) {
+- err = ext4_get_block(inode, block, bh, 0);
+- if (err) {
+- folio_set_error(folio);
++ int err = ext4_get_block(inode, block, bh, 0);
++ if (err)
+ return err;
+- }
+ if (!buffer_mapped(bh)) {
+ folio_zero_range(folio, block_start, blocksize);
+ set_buffer_uptodate(bh);
+ continue;
+ }
+ }
+- BUG_ON(nr >= MAX_BUF_PER_PAGE);
+- arr[nr++] = bh;
++ lock_buffer(bh);
++ if (buffer_uptodate(bh)) {
++ unlock_buffer(bh);
++ continue;
++ }
++ ext4_read_bh_nowait(bh, 0, NULL, false);
++ nr++;
+ }
+ /* No io required */
+ if (!nr)
+ goto out;
+
+- for (i = 0; i < nr; i++) {
+- bh = arr[i];
+- if (!bh_uptodate_or_lock(bh)) {
+- err = ext4_read_bh(bh, 0, NULL);
+- if (err)
+- return err;
+- }
+- }
++ bh = head;
++ do {
++ if (bh_offset(bh) + blocksize <= from)
++ continue;
++ if (bh_offset(bh) > to)
++ break;
++ wait_on_buffer(bh);
++ if (buffer_uptodate(bh))
++ continue;
++ return -EIO;
++ } while ((bh = bh->b_this_page) != head);
+ out:
+ if (!partial)
+ folio_mark_uptodate(folio);
+diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
+index dfdd7e5cf03890..7ab4f5a9bf5b87 100644
+--- a/fs/ext4/page-io.c
++++ b/fs/ext4/page-io.c
+@@ -117,7 +117,6 @@ static void ext4_finish_bio(struct bio *bio)
+
+ if (bio->bi_status) {
+ int err = blk_status_to_errno(bio->bi_status);
+- folio_set_error(folio);
+ mapping_set_error(folio->mapping, err);
+ }
+ bh = head = folio_buffers(folio);
+@@ -441,8 +440,6 @@ int ext4_bio_write_folio(struct ext4_io_submit *io, struct folio *folio,
+ BUG_ON(!folio_test_locked(folio));
+ BUG_ON(folio_test_writeback(folio));
+
+- folio_clear_error(folio);
+-
+ /*
+ * Comments copied from block_write_full_page:
+ *
+diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
+index 3e7d160f543f0c..8cb83e7b699bd0 100644
+--- a/fs/ext4/readpage.c
++++ b/fs/ext4/readpage.c
+@@ -296,7 +296,6 @@ int ext4_mpage_readpages(struct inode *inode,
+
+ if (ext4_map_blocks(NULL, inode, &map, 0) < 0) {
+ set_error_page:
+- folio_set_error(folio);
+ folio_zero_segment(folio, 0,
+ folio_size(folio));
+ folio_unlock(folio);
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 5f105171df7b56..b34007541e08cc 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1301,7 +1301,7 @@ static struct buffer_head *ext4_get_bitmap(struct super_block *sb, __u64 block)
+ if (unlikely(!bh))
+ return NULL;
+ if (!bh_uptodate_or_lock(bh)) {
+- if (ext4_read_bh(bh, 0, NULL) < 0) {
++ if (ext4_read_bh(bh, 0, NULL, false) < 0) {
+ brelse(bh);
+ return NULL;
+ }
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 1d14a38017a7f0..2346ef071b2421 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -161,8 +161,14 @@ MODULE_ALIAS("ext3");
+
+
+ static inline void __ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags,
+- bh_end_io_t *end_io)
++ bh_end_io_t *end_io, bool simu_fail)
+ {
++ if (simu_fail) {
++ clear_buffer_uptodate(bh);
++ unlock_buffer(bh);
++ return;
++ }
++
+ /*
+ * buffer's verified bit is no longer valid after reading from
+ * disk again due to write out error, clear it to make sure we
+@@ -176,7 +182,7 @@ static inline void __ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags,
+ }
+
+ void ext4_read_bh_nowait(struct buffer_head *bh, blk_opf_t op_flags,
+- bh_end_io_t *end_io)
++ bh_end_io_t *end_io, bool simu_fail)
+ {
+ BUG_ON(!buffer_locked(bh));
+
+@@ -184,10 +190,11 @@ void ext4_read_bh_nowait(struct buffer_head *bh, blk_opf_t op_flags,
+ unlock_buffer(bh);
+ return;
+ }
+- __ext4_read_bh(bh, op_flags, end_io);
++ __ext4_read_bh(bh, op_flags, end_io, simu_fail);
+ }
+
+-int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags, bh_end_io_t *end_io)
++int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags,
++ bh_end_io_t *end_io, bool simu_fail)
+ {
+ BUG_ON(!buffer_locked(bh));
+
+@@ -196,7 +203,7 @@ int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags, bh_end_io_t *end_io
+ return 0;
+ }
+
+- __ext4_read_bh(bh, op_flags, end_io);
++ __ext4_read_bh(bh, op_flags, end_io, simu_fail);
+
+ wait_on_buffer(bh);
+ if (buffer_uptodate(bh))
+@@ -208,10 +215,10 @@ int ext4_read_bh_lock(struct buffer_head *bh, blk_opf_t op_flags, bool wait)
+ {
+ lock_buffer(bh);
+ if (!wait) {
+- ext4_read_bh_nowait(bh, op_flags, NULL);
++ ext4_read_bh_nowait(bh, op_flags, NULL, false);
+ return 0;
+ }
+- return ext4_read_bh(bh, op_flags, NULL);
++ return ext4_read_bh(bh, op_flags, NULL, false);
+ }
+
+ /*
+@@ -259,7 +266,7 @@ void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block)
+
+ if (likely(bh)) {
+ if (trylock_buffer(bh))
+- ext4_read_bh_nowait(bh, REQ_RAHEAD, NULL);
++ ext4_read_bh_nowait(bh, REQ_RAHEAD, NULL, false);
+ brelse(bh);
+ }
+ }
+@@ -339,9 +346,9 @@ __u32 ext4_free_group_clusters(struct super_block *sb,
+ __u32 ext4_free_inodes_count(struct super_block *sb,
+ struct ext4_group_desc *bg)
+ {
+- return le16_to_cpu(bg->bg_free_inodes_count_lo) |
++ return le16_to_cpu(READ_ONCE(bg->bg_free_inodes_count_lo)) |
+ (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+- (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
++ (__u32)le16_to_cpu(READ_ONCE(bg->bg_free_inodes_count_hi)) << 16 : 0);
+ }
+
+ __u32 ext4_used_dirs_count(struct super_block *sb,
+@@ -395,9 +402,9 @@ void ext4_free_group_clusters_set(struct super_block *sb,
+ void ext4_free_inodes_set(struct super_block *sb,
+ struct ext4_group_desc *bg, __u32 count)
+ {
+- bg->bg_free_inodes_count_lo = cpu_to_le16((__u16)count);
++ WRITE_ONCE(bg->bg_free_inodes_count_lo, cpu_to_le16((__u16)count));
+ if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+- bg->bg_free_inodes_count_hi = cpu_to_le16(count >> 16);
++ WRITE_ONCE(bg->bg_free_inodes_count_hi, cpu_to_le16(count >> 16));
+ }
+
+ void ext4_used_dirs_set(struct super_block *sb,
+@@ -6544,9 +6551,6 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
+ goto restore_opts;
+ }
+
+- if (test_opt2(sb, ABORT))
+- ext4_abort(sb, ESHUTDOWN, "Abort forced by user");
+-
+ sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
+ (test_opt(sb, POSIX_ACL) ? SB_POSIXACL : 0);
+
+@@ -6715,6 +6719,14 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
+ if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
+ ext4_stop_mmpd(sbi);
+
++ /*
++ * Handle aborting the filesystem as the last thing during remount to
++ * avoid obsure errors during remount when some option changes fail to
++ * apply due to shutdown filesystem.
++ */
++ if (test_opt2(sb, ABORT))
++ ext4_abort(sb, ESHUTDOWN, "Abort forced by user");
++
+ return 0;
+
+ restore_opts:
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 1a33a8c1623f24..c6317596e695cc 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -32,7 +32,7 @@ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
+ f2fs_build_fault_attr(sbi, 0, 0);
+ if (!end_io)
+ f2fs_flush_merged_writes(sbi);
+- f2fs_handle_critical_error(sbi, reason, end_io);
++ f2fs_handle_critical_error(sbi, reason);
+ }
+
+ /*
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 1c59a3b2b2c348..acd0764b0286c8 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -924,6 +924,7 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
+ #ifdef CONFIG_BLK_DEV_ZONED
+ static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
+ {
++ struct block_device *bdev = sbi->sb->s_bdev;
+ int devi = 0;
+
+ if (f2fs_is_multi_device(sbi)) {
+@@ -934,8 +935,9 @@ static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
+ return false;
+ }
+ blkaddr -= FDEV(devi).start_blk;
++ bdev = FDEV(devi).bdev;
+ }
+- return bdev_zoned_model(FDEV(devi).bdev) == BLK_ZONED_HM &&
++ return bdev_is_zoned(bdev) &&
+ f2fs_blkz_is_seq(sbi, devi, blkaddr) &&
+ (blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1);
+ }
+@@ -1873,25 +1875,6 @@ static int f2fs_xattr_fiemap(struct inode *inode,
+ return (err < 0 ? err : 0);
+ }
+
+-static loff_t max_inode_blocks(struct inode *inode)
+-{
+- loff_t result = ADDRS_PER_INODE(inode);
+- loff_t leaf_count = ADDRS_PER_BLOCK(inode);
+-
+- /* two direct node blocks */
+- result += (leaf_count * 2);
+-
+- /* two indirect node blocks */
+- leaf_count *= NIDS_PER_BLOCK;
+- result += (leaf_count * 2);
+-
+- /* one double indirect node block */
+- leaf_count *= NIDS_PER_BLOCK;
+- result += leaf_count;
+-
+- return result;
+-}
+-
+ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ u64 start, u64 len)
+ {
+@@ -1964,8 +1947,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) {
+ start_blk = next_pgofs;
+
+- if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode,
+- max_inode_blocks(inode)))
++ if (blks_to_bytes(inode, start_blk) < maxbytes)
+ goto prep_next;
+
+ flags |= FIEMAP_EXTENT_LAST;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 7faf9446ea5dcb..33620642ae5ec8 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3588,8 +3588,7 @@ int f2fs_quota_sync(struct super_block *sb, int type);
+ loff_t max_file_blocks(struct inode *inode);
+ void f2fs_quota_off_umount(struct super_block *sb);
+ void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag);
+-void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason,
+- bool irq_context);
++void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason);
+ void f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error);
+ void f2fs_handle_error_async(struct f2fs_sb_info *sbi, unsigned char error);
+ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 74fac935bd0923..196755a34833d2 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -846,7 +846,11 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw)
+ return true;
+ if (f2fs_compressed_file(inode))
+ return true;
+- if (f2fs_has_inline_data(inode))
++ /*
++ * only force direct read to use buffered IO, for direct write,
++ * it expects inline data conversion before committing IO.
++ */
++ if (f2fs_has_inline_data(inode) && rw == READ)
+ return true;
+
+ /* disallow direct IO if any of devices has unaligned blksize */
+@@ -2308,9 +2312,12 @@ int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,
+ if (readonly)
+ goto out;
+
+- /* grab sb->s_umount to avoid racing w/ remount() */
++ /*
++ * grab sb->s_umount to avoid racing w/ remount() and other shutdown
++ * paths.
++ */
+ if (need_lock)
+- down_read(&sbi->sb->s_umount);
++ down_write(&sbi->sb->s_umount);
+
+ f2fs_stop_gc_thread(sbi);
+ f2fs_stop_discard_thread(sbi);
+@@ -2319,7 +2326,7 @@ int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,
+ clear_opt(sbi, DISCARD);
+
+ if (need_lock)
+- up_read(&sbi->sb->s_umount);
++ up_write(&sbi->sb->s_umount);
+
+ f2fs_update_time(sbi, REQ_TIME);
+ out:
+@@ -3755,7 +3762,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
+ to_reserved = cluster_size - compr_blocks - reserved;
+
+ /* for the case all blocks in cluster were reserved */
+- if (to_reserved == 1) {
++ if (reserved && to_reserved == 1) {
+ dn->ofs_in_node += cluster_size;
+ goto next;
+ }
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 888c301ffe8f4c..e9904158241460 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -228,6 +228,8 @@ static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)
+
+ switch (sbi->gc_mode) {
+ case GC_IDLE_CB:
++ case GC_URGENT_LOW:
++ case GC_URGENT_MID:
+ gc_mode = GC_CB;
+ break;
+ case GC_IDLE_GREEDY:
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index c765bda3beaacb..a9ab93d30dceb8 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -905,6 +905,16 @@ static int truncate_node(struct dnode_of_data *dn)
+ if (err)
+ return err;
+
++ if (ni.blk_addr != NEW_ADDR &&
++ !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC_ENHANCE)) {
++ f2fs_err_ratelimited(sbi,
++ "nat entry is corrupted, run fsck to fix it, ino:%u, "
++ "nid:%u, blkaddr:%u", ni.ino, ni.nid, ni.blk_addr);
++ set_sbi_flag(sbi, SBI_NEED_FSCK);
++ f2fs_handle_error(sbi, ERROR_INCONSISTENT_NAT);
++ return -EFSCORRUPTED;
++ }
++
+ /* Deallocate node address */
+ f2fs_invalidate_blocks(sbi, ni.blk_addr);
+ dec_valid_node_count(sbi, dn->inode, dn->nid == dn->inode->i_ino);
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index c0ba379a6d8f3e..670104628ddbea 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2848,7 +2848,8 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)
+ struct f2fs_summary_block *sum_node;
+ struct page *sum_page;
+
+- write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno));
++ if (curseg->inited)
++ write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno));
+
+ __set_test_and_inuse(sbi, new_segno);
+
+@@ -3757,8 +3758,8 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ }
+ }
+
+- f2fs_bug_on(sbi, !IS_DATASEG(type));
+ curseg = CURSEG_I(sbi, type);
++ f2fs_bug_on(sbi, !IS_DATASEG(curseg->seg_type));
+
+ mutex_lock(&curseg->curseg_mutex);
+ down_write(&sit_i->sentry_lock);
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 952970166d5da8..cd2ec6acc71776 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -559,18 +559,21 @@ static inline int reserved_sections(struct f2fs_sb_info *sbi)
+ }
+
+ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi,
+- unsigned int node_blocks, unsigned int dent_blocks)
++ unsigned int node_blocks, unsigned int data_blocks,
++ unsigned int dent_blocks)
+ {
+
+- unsigned segno, left_blocks;
++ unsigned int segno, left_blocks, blocks;
+ int i;
+
+- /* check current node sections in the worst case. */
+- for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
++ /* check current data/node sections in the worst case. */
++ for (i = CURSEG_HOT_DATA; i < NR_PERSISTENT_LOG; i++) {
+ segno = CURSEG_I(sbi, i)->segno;
+ left_blocks = CAP_BLKS_PER_SEC(sbi) -
+ get_ckpt_valid_blocks(sbi, segno, true);
+- if (node_blocks > left_blocks)
++
++ blocks = i <= CURSEG_COLD_DATA ? data_blocks : node_blocks;
++ if (blocks > left_blocks)
+ return false;
+ }
+
+@@ -584,8 +587,9 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi,
+ }
+
+ /*
+- * calculate needed sections for dirty node/dentry
+- * and call has_curseg_enough_space
++ * calculate needed sections for dirty node/dentry and call
++ * has_curseg_enough_space, please note that, it needs to account
++ * dirty data as well in lfs mode when checkpoint is disabled.
+ */
+ static inline void __get_secs_required(struct f2fs_sb_info *sbi,
+ unsigned int *lower_p, unsigned int *upper_p, bool *curseg_p)
+@@ -594,19 +598,30 @@ static inline void __get_secs_required(struct f2fs_sb_info *sbi,
+ get_pages(sbi, F2FS_DIRTY_DENTS) +
+ get_pages(sbi, F2FS_DIRTY_IMETA);
+ unsigned int total_dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS);
++ unsigned int total_data_blocks = 0;
+ unsigned int node_secs = total_node_blocks / CAP_BLKS_PER_SEC(sbi);
+ unsigned int dent_secs = total_dent_blocks / CAP_BLKS_PER_SEC(sbi);
++ unsigned int data_secs = 0;
+ unsigned int node_blocks = total_node_blocks % CAP_BLKS_PER_SEC(sbi);
+ unsigned int dent_blocks = total_dent_blocks % CAP_BLKS_PER_SEC(sbi);
++ unsigned int data_blocks = 0;
++
++ if (f2fs_lfs_mode(sbi) &&
++ unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
++ total_data_blocks = get_pages(sbi, F2FS_DIRTY_DATA);
++ data_secs = total_data_blocks / CAP_BLKS_PER_SEC(sbi);
++ data_blocks = total_data_blocks % CAP_BLKS_PER_SEC(sbi);
++ }
+
+ if (lower_p)
+- *lower_p = node_secs + dent_secs;
++ *lower_p = node_secs + dent_secs + data_secs;
+ if (upper_p)
+ *upper_p = node_secs + dent_secs +
+- (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0);
++ (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0) +
++ (data_blocks ? 1 : 0);
+ if (curseg_p)
+ *curseg_p = has_curseg_enough_space(sbi,
+- node_blocks, dent_blocks);
++ node_blocks, data_blocks, dent_blocks);
+ }
+
+ static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 540fa1dfc77dff..f05d0e43db9e22 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4093,8 +4093,7 @@ static bool system_going_down(void)
+ || system_state == SYSTEM_RESTART;
+ }
+
+-void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason,
+- bool irq_context)
++void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason)
+ {
+ struct super_block *sb = sbi->sb;
+ bool shutdown = reason == STOP_CP_REASON_SHUTDOWN;
+@@ -4106,10 +4105,12 @@ void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason,
+ if (!f2fs_hw_is_readonly(sbi)) {
+ save_stop_reason(sbi, reason);
+
+- if (irq_context && !shutdown)
+- schedule_work(&sbi->s_error_work);
+- else
+- f2fs_record_stop_reason(sbi);
++ /*
++ * always create an asynchronous task to record stop_reason
++ * in order to avoid potential deadlock when running into
++ * f2fs_record_stop_reason() synchronously.
++ */
++ schedule_work(&sbi->s_error_work);
+ }
+
+ /*
+diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c
+index cb75c07b5281a5..ced14ac78cc1c2 100644
+--- a/fs/fscache/volume.c
++++ b/fs/fscache/volume.c
+@@ -322,8 +322,7 @@ void fscache_create_volume(struct fscache_volume *volume, bool wait)
+ }
+ return;
+ no_wait:
+- clear_bit_unlock(FSCACHE_VOLUME_CREATING, &volume->flags);
+- wake_up_bit(&volume->flags, FSCACHE_VOLUME_CREATING);
++ clear_and_wake_up_bit(FSCACHE_VOLUME_CREATING, &volume->flags);
+ }
+
+ /*
+diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
+index 685e3ef9e9008d..2c0908a3021026 100644
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -274,7 +274,7 @@ static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
+ * Enqueue the glock on the work queue. Passes one glock reference on to the
+ * work queue.
+ */
+-static void __gfs2_glock_queue_work(struct gfs2_glock *gl, unsigned long delay) {
++static void gfs2_glock_queue_work(struct gfs2_glock *gl, unsigned long delay) {
+ if (!queue_delayed_work(glock_workqueue, &gl->gl_work, delay)) {
+ /*
+ * We are holding the lockref spinlock, and the work was still
+@@ -287,12 +287,6 @@ static void __gfs2_glock_queue_work(struct gfs2_glock *gl, unsigned long delay)
+ }
+ }
+
+-static void gfs2_glock_queue_work(struct gfs2_glock *gl, unsigned long delay) {
+- spin_lock(&gl->gl_lockref.lock);
+- __gfs2_glock_queue_work(gl, delay);
+- spin_unlock(&gl->gl_lockref.lock);
+-}
+-
+ static void __gfs2_glock_put(struct gfs2_glock *gl)
+ {
+ struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+@@ -311,14 +305,6 @@ static void __gfs2_glock_put(struct gfs2_glock *gl)
+ sdp->sd_lockstruct.ls_ops->lm_put_lock(gl);
+ }
+
+-/*
+- * Cause the glock to be put in work queue context.
+- */
+-void gfs2_glock_queue_put(struct gfs2_glock *gl)
+-{
+- gfs2_glock_queue_work(gl, 0);
+-}
+-
+ /**
+ * gfs2_glock_put() - Decrement reference count on glock
+ * @gl: The glock to put
+@@ -333,6 +319,23 @@ void gfs2_glock_put(struct gfs2_glock *gl)
+ __gfs2_glock_put(gl);
+ }
+
++/*
++ * gfs2_glock_put_async - Decrement reference count without sleeping
++ * @gl: The glock to put
++ *
++ * Decrement the reference count on glock immediately unless it is the last
++ * reference. Defer putting the last reference to work queue context.
++ */
++void gfs2_glock_put_async(struct gfs2_glock *gl)
++{
++ if (lockref_put_or_lock(&gl->gl_lockref))
++ return;
++
++ GLOCK_BUG_ON(gl, gl->gl_lockref.count != 1);
++ gfs2_glock_queue_work(gl, 0);
++ spin_unlock(&gl->gl_lockref.lock);
++}
++
+ /**
+ * may_grant - check if it's ok to grant a new lock
+ * @gl: The glock
+@@ -806,7 +809,7 @@ __acquires(&gl->gl_lockref.lock)
+ */
+ clear_bit(GLF_LOCK, &gl->gl_flags);
+ clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
+- __gfs2_glock_queue_work(gl, GL_GLOCK_DFT_HOLD);
++ gfs2_glock_queue_work(gl, GL_GLOCK_DFT_HOLD);
+ return;
+ } else {
+ clear_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags);
+@@ -836,7 +839,7 @@ __acquires(&gl->gl_lockref.lock)
+
+ /* Complete the operation now. */
+ finish_xmote(gl, target);
+- __gfs2_glock_queue_work(gl, 0);
++ gfs2_glock_queue_work(gl, 0);
+ }
+
+ /**
+@@ -883,7 +886,7 @@ __acquires(&gl->gl_lockref.lock)
+ clear_bit(GLF_LOCK, &gl->gl_flags);
+ smp_mb__after_atomic();
+ gl->gl_lockref.count++;
+- __gfs2_glock_queue_work(gl, 0);
++ gfs2_glock_queue_work(gl, 0);
+ return;
+
+ out_unlock:
+@@ -1020,14 +1023,15 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl)
+ &gl->gl_delete, 0);
+ }
+
+-static bool gfs2_queue_verify_evict(struct gfs2_glock *gl)
++bool gfs2_queue_verify_delete(struct gfs2_glock *gl, bool later)
+ {
+ struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
++ unsigned long delay;
+
+- if (test_and_set_bit(GLF_VERIFY_EVICT, &gl->gl_flags))
++ if (test_and_set_bit(GLF_VERIFY_DELETE, &gl->gl_flags))
+ return false;
+- return queue_delayed_work(sdp->sd_delete_wq,
+- &gl->gl_delete, 5 * HZ);
++ delay = later ? 5 * HZ : 0;
++ return queue_delayed_work(sdp->sd_delete_wq, &gl->gl_delete, delay);
+ }
+
+ static void delete_work_func(struct work_struct *work)
+@@ -1059,19 +1063,19 @@ static void delete_work_func(struct work_struct *work)
+ if (gfs2_try_evict(gl)) {
+ if (test_bit(SDF_KILL, &sdp->sd_flags))
+ goto out;
+- if (gfs2_queue_verify_evict(gl))
++ if (gfs2_queue_verify_delete(gl, true))
+ return;
+ }
+ goto out;
+ }
+
+- if (test_and_clear_bit(GLF_VERIFY_EVICT, &gl->gl_flags)) {
++ if (test_and_clear_bit(GLF_VERIFY_DELETE, &gl->gl_flags)) {
+ inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino,
+ GFS2_BLKST_UNLINKED);
+ if (IS_ERR(inode)) {
+ if (PTR_ERR(inode) == -EAGAIN &&
+ !test_bit(SDF_KILL, &sdp->sd_flags) &&
+- gfs2_queue_verify_evict(gl))
++ gfs2_queue_verify_delete(gl, true))
+ return;
+ } else {
+ d_prune_aliases(inode);
+@@ -1115,12 +1119,12 @@ static void glock_work_func(struct work_struct *work)
+ drop_refs--;
+ if (gl->gl_name.ln_type != LM_TYPE_INODE)
+ delay = 0;
+- __gfs2_glock_queue_work(gl, delay);
++ gfs2_glock_queue_work(gl, delay);
+ }
+
+ /*
+ * Drop the remaining glock references manually here. (Mind that
+- * __gfs2_glock_queue_work depends on the lockref spinlock begin held
++ * gfs2_glock_queue_work depends on the lockref spinlock begin held
+ * here as well.)
+ */
+ gl->gl_lockref.count -= drop_refs;
+@@ -1607,7 +1611,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
+ test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))) {
+ set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
+ gl->gl_lockref.count++;
+- __gfs2_glock_queue_work(gl, 0);
++ gfs2_glock_queue_work(gl, 0);
+ }
+ run_queue(gl, 1);
+ spin_unlock(&gl->gl_lockref.lock);
+@@ -1672,7 +1676,7 @@ static void __gfs2_glock_dq(struct gfs2_holder *gh)
+ !test_bit(GLF_DEMOTE, &gl->gl_flags) &&
+ gl->gl_name.ln_type == LM_TYPE_INODE)
+ delay = gl->gl_hold_time;
+- __gfs2_glock_queue_work(gl, delay);
++ gfs2_glock_queue_work(gl, delay);
+ }
+ }
+
+@@ -1896,7 +1900,7 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
+ delay = gl->gl_hold_time;
+ }
+ handle_callback(gl, state, delay, true);
+- __gfs2_glock_queue_work(gl, delay);
++ gfs2_glock_queue_work(gl, delay);
+ spin_unlock(&gl->gl_lockref.lock);
+ }
+
+@@ -1956,7 +1960,7 @@ void gfs2_glock_complete(struct gfs2_glock *gl, int ret)
+
+ gl->gl_lockref.count++;
+ set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
+- __gfs2_glock_queue_work(gl, 0);
++ gfs2_glock_queue_work(gl, 0);
+ spin_unlock(&gl->gl_lockref.lock);
+ }
+
+@@ -2009,15 +2013,14 @@ __acquires(&lru_lock)
+ atomic_inc(&lru_count);
+ continue;
+ }
+- if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
++ if (test_bit(GLF_LOCK, &gl->gl_flags)) {
+ spin_unlock(&gl->gl_lockref.lock);
+ goto add_back_to_lru;
+ }
+ gl->gl_lockref.count++;
+ if (demote_ok(gl))
+ handle_callback(gl, LM_ST_UNLOCKED, 0, false);
+- WARN_ON(!test_and_clear_bit(GLF_LOCK, &gl->gl_flags));
+- __gfs2_glock_queue_work(gl, 0);
++ gfs2_glock_queue_work(gl, 0);
+ spin_unlock(&gl->gl_lockref.lock);
+ cond_resched_lock(&lru_lock);
+ }
+@@ -2117,7 +2120,7 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
+ void gfs2_cancel_delete_work(struct gfs2_glock *gl)
+ {
+ clear_bit(GLF_TRY_TO_EVICT, &gl->gl_flags);
+- clear_bit(GLF_VERIFY_EVICT, &gl->gl_flags);
++ clear_bit(GLF_VERIFY_DELETE, &gl->gl_flags);
+ if (cancel_delayed_work(&gl->gl_delete))
+ gfs2_glock_put(gl);
+ }
+@@ -2155,7 +2158,7 @@ static void thaw_glock(struct gfs2_glock *gl)
+
+ spin_lock(&gl->gl_lockref.lock);
+ set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
+- __gfs2_glock_queue_work(gl, 0);
++ gfs2_glock_queue_work(gl, 0);
+ spin_unlock(&gl->gl_lockref.lock);
+ }
+
+@@ -2174,7 +2177,7 @@ static void clear_glock(struct gfs2_glock *gl)
+ gl->gl_lockref.count++;
+ if (gl->gl_state != LM_ST_UNLOCKED)
+ handle_callback(gl, LM_ST_UNLOCKED, 0, false);
+- __gfs2_glock_queue_work(gl, 0);
++ gfs2_glock_queue_work(gl, 0);
+ }
+ spin_unlock(&gl->gl_lockref.lock);
+ }
+@@ -2354,7 +2357,7 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)
+ *p++ = 'N';
+ if (test_bit(GLF_TRY_TO_EVICT, gflags))
+ *p++ = 'e';
+- if (test_bit(GLF_VERIFY_EVICT, gflags))
++ if (test_bit(GLF_VERIFY_DELETE, gflags))
+ *p++ = 'E';
+ *p = 0;
+ return buf;
+@@ -2533,8 +2536,7 @@ static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)
+ if (gl) {
+ if (n == 0)
+ return;
+- if (!lockref_put_not_zero(&gl->gl_lockref))
+- gfs2_glock_queue_put(gl);
++ gfs2_glock_put_async(gl);
+ }
+ for (;;) {
+ gl = rhashtable_walk_next(&gi->hti);
+diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
+index f7ee9ca948eeea..aae9fabbb76cc0 100644
+--- a/fs/gfs2/glock.h
++++ b/fs/gfs2/glock.h
+@@ -186,7 +186,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
+ int create, struct gfs2_glock **glp);
+ struct gfs2_glock *gfs2_glock_hold(struct gfs2_glock *gl);
+ void gfs2_glock_put(struct gfs2_glock *gl);
+-void gfs2_glock_queue_put(struct gfs2_glock *gl);
++void gfs2_glock_put_async(struct gfs2_glock *gl);
+
+ void __gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
+ u16 flags, struct gfs2_holder *gh,
+@@ -259,6 +259,7 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,
+ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state);
+ void gfs2_glock_complete(struct gfs2_glock *gl, int ret);
+ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl);
++bool gfs2_queue_verify_delete(struct gfs2_glock *gl, bool later);
+ void gfs2_cancel_delete_work(struct gfs2_glock *gl);
+ void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
+ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
+diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
+index 60abd7050c9983..853fad2bc48551 100644
+--- a/fs/gfs2/incore.h
++++ b/fs/gfs2/incore.h
+@@ -331,7 +331,7 @@ enum {
+ GLF_BLOCKING = 15,
+ GLF_FREEING = 16, /* Wait for glock to be freed */
+ GLF_TRY_TO_EVICT = 17, /* iopen glocks only */
+- GLF_VERIFY_EVICT = 18, /* iopen glocks only */
++ GLF_VERIFY_DELETE = 18, /* iopen glocks only */
+ };
+
+ struct gfs2_glock {
+diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
+index 767549066066c2..2be5551241b3ad 100644
+--- a/fs/gfs2/log.c
++++ b/fs/gfs2/log.c
+@@ -790,7 +790,7 @@ void gfs2_glock_remove_revoke(struct gfs2_glock *gl)
+ {
+ if (atomic_dec_return(&gl->gl_revokes) == 0) {
+ clear_bit(GLF_LFLUSH, &gl->gl_flags);
+- gfs2_glock_queue_put(gl);
++ gfs2_glock_put_async(gl);
+ }
+ }
+
+diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
+index 396d0f4a259d53..4a5e2732d1da2f 100644
+--- a/fs/gfs2/rgrp.c
++++ b/fs/gfs2/rgrp.c
+@@ -1879,7 +1879,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
+ */
+ ip = gl->gl_object;
+
+- if (ip || !gfs2_queue_try_to_evict(gl))
++ if (ip || !gfs2_queue_verify_delete(gl, false))
+ gfs2_glock_put(gl);
+ else
+ found++;
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index 1200cb80599957..09285dc782cf8a 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1053,8 +1053,8 @@ static int gfs2_drop_inode(struct inode *inode)
+ struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
+
+ gfs2_glock_hold(gl);
+- if (!gfs2_queue_try_to_evict(gl))
+- gfs2_glock_queue_put(gl);
++ if (!gfs2_queue_verify_delete(gl, true))
++ gfs2_glock_put_async(gl);
+ return 0;
+ }
+
+@@ -1270,7 +1270,7 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
+ static void gfs2_glock_put_eventually(struct gfs2_glock *gl)
+ {
+ if (current->flags & PF_MEMALLOC)
+- gfs2_glock_queue_put(gl);
++ gfs2_glock_put_async(gl);
+ else
+ gfs2_glock_put(gl);
+ }
+diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
+index b65261e0cae3a8..268ff47b039636 100644
+--- a/fs/gfs2/util.c
++++ b/fs/gfs2/util.c
+@@ -255,7 +255,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)
+ gfs2_glock_nq(&sdp->sd_live_gh);
+ }
+
+- gfs2_glock_queue_put(live_gl); /* drop extra reference we acquired */
++ gfs2_glock_put(live_gl); /* drop extra reference we acquired */
+ clear_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags);
+
+ /*
+diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
+index 583c196ecd5206..1473b04fc0f311 100644
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -156,6 +156,7 @@ struct hfsplus_sb_info {
+
+ /* Runtime variables */
+ u32 blockoffset;
++ u32 min_io_size;
+ sector_t part_start;
+ sector_t sect_count;
+ int fs_shift;
+@@ -306,7 +307,7 @@ struct hfsplus_readdir_data {
+ */
+ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
+ {
+- return max_t(unsigned short, bdev_logical_block_size(sb->s_bdev),
++ return max_t(unsigned short, HFSPLUS_SB(sb)->min_io_size,
+ HFSPLUS_SECTOR_SIZE);
+ }
+
+diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
+index 0b791adf02e53d..a51a58db3fef04 100644
+--- a/fs/hfsplus/wrapper.c
++++ b/fs/hfsplus/wrapper.c
+@@ -171,6 +171,8 @@ int hfsplus_read_wrapper(struct super_block *sb)
+ if (!blocksize)
+ goto out;
+
++ sbi->min_io_size = blocksize;
++
+ if (hfsplus_get_last_session(sb, &part_start, &part_size))
+ goto out;
+
+diff --git a/fs/inode.c b/fs/inode.c
+index 9cafde77e2b038..030e07b169c276 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -593,6 +593,7 @@ void dump_mapping(const struct address_space *mapping)
+ struct hlist_node *dentry_first;
+ struct dentry *dentry_ptr;
+ struct dentry dentry;
++ char fname[64] = {};
+ unsigned long ino;
+
+ /*
+@@ -628,11 +629,14 @@ void dump_mapping(const struct address_space *mapping)
+ return;
+ }
+
++ if (strncpy_from_kernel_nofault(fname, dentry.d_name.name, 63) < 0)
++ strscpy(fname, "<invalid>", 63);
+ /*
+- * if dentry is corrupted, the %pd handler may still crash,
+- * but it's unlikely that we reach here with a corrupt mapping
++ * Even if strncpy_from_kernel_nofault() succeeded,
++ * the fname could be unreliable
+ */
+- pr_warn("aops:%ps ino:%lx dentry name:\"%pd\"\n", a_ops, ino, &dentry);
++ pr_warn("aops:%ps ino:%lx dentry name(?):\"%s\"\n",
++ a_ops, ino, fname);
+ }
+
+ void clear_inode(struct inode *inode)
+diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
+index acd32f05b51988..ef3a1e1b6cb065 100644
+--- a/fs/jffs2/erase.c
++++ b/fs/jffs2/erase.c
+@@ -338,10 +338,9 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
+ } while(--retlen);
+ mtd_unpoint(c->mtd, jeb->offset, c->sector_size);
+ if (retlen) {
+- pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
+- *wordebuf,
+- jeb->offset +
+- c->sector_size-retlen * sizeof(*wordebuf));
++ *bad_offset = jeb->offset + c->sector_size - retlen * sizeof(*wordebuf);
++ pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08x\n",
++ *wordebuf, *bad_offset);
+ return -EIO;
+ }
+ return 0;
+diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
+index 49e064c1f55179..7252941bf165bc 100644
+--- a/fs/jfs/xattr.c
++++ b/fs/jfs/xattr.c
+@@ -559,7 +559,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
+
+ size_check:
+ if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
+- int size = min_t(int, EALIST_SIZE(ea_buf->xattr), ea_size);
++ int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
+
+ printk(KERN_ERR "ea_get: invalid extended attribute\n");
+ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index 8bceaac2205c87..a92b234ae0870b 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -11,7 +11,7 @@
+ #include <linux/nfs_page.h>
+ #include <linux/wait_bit.h>
+
+-#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
++#define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
+
+ extern const struct export_operations nfs_export_ops;
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 299ea2b86df668..4b12e45f575394 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -2528,12 +2528,14 @@ static void nfs4_open_release(void *calldata)
+ struct nfs4_opendata *data = calldata;
+ struct nfs4_state *state = NULL;
+
++ /* In case of error, no cleanup! */
++ if (data->rpc_status != 0 || !data->rpc_done) {
++ nfs_release_seqid(data->o_arg.seqid);
++ goto out_free;
++ }
+ /* If this request hasn't been cancelled, do nothing */
+ if (!data->cancelled)
+ goto out_free;
+- /* In case of error, no cleanup! */
+- if (data->rpc_status != 0 || !data->rpc_done)
+- goto out_free;
+ /* In case we need an open_confirm, no cleanup! */
+ if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
+ goto out_free;
+diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
+index b7da17e530077e..d4d3ec58047e82 100644
+--- a/fs/nfsd/export.c
++++ b/fs/nfsd/export.c
+@@ -40,15 +40,24 @@
+ #define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
+ #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
+
+-static void expkey_put(struct kref *ref)
++static void expkey_put_work(struct work_struct *work)
+ {
+- struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
++ struct svc_expkey *key =
++ container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work);
+
+ if (test_bit(CACHE_VALID, &key->h.flags) &&
+ !test_bit(CACHE_NEGATIVE, &key->h.flags))
+ path_put(&key->ek_path);
+ auth_domain_put(key->ek_client);
+- kfree_rcu(key, ek_rcu);
++ kfree(key);
++}
++
++static void expkey_put(struct kref *ref)
++{
++ struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
++
++ INIT_RCU_WORK(&key->ek_rcu_work, expkey_put_work);
++ queue_rcu_work(system_wq, &key->ek_rcu_work);
+ }
+
+ static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
+@@ -351,16 +360,26 @@ static void export_stats_destroy(struct export_stats *stats)
+ EXP_STATS_COUNTERS_NUM);
+ }
+
+-static void svc_export_put(struct kref *ref)
++static void svc_export_put_work(struct work_struct *work)
+ {
+- struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
++ struct svc_export *exp =
++ container_of(to_rcu_work(work), struct svc_export, ex_rcu_work);
++
+ path_put(&exp->ex_path);
+ auth_domain_put(exp->ex_client);
+ nfsd4_fslocs_free(&exp->ex_fslocs);
+ export_stats_destroy(exp->ex_stats);
+ kfree(exp->ex_stats);
+ kfree(exp->ex_uuid);
+- kfree_rcu(exp, ex_rcu);
++ kfree(exp);
++}
++
++static void svc_export_put(struct kref *ref)
++{
++ struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
++
++ INIT_RCU_WORK(&exp->ex_rcu_work, svc_export_put_work);
++ queue_rcu_work(system_wq, &exp->ex_rcu_work);
+ }
+
+ static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
+@@ -1366,9 +1385,12 @@ static int e_show(struct seq_file *m, void *p)
+ return 0;
+ }
+
+- exp_get(exp);
++ if (!cache_get_rcu(&exp->h))
++ return 0;
++
+ if (cache_check(cd, &exp->h, NULL))
+ return 0;
++
+ exp_put(exp);
+ return svc_export_show(m, cd, cp);
+ }
+diff --git a/fs/nfsd/export.h b/fs/nfsd/export.h
+index ca9dc230ae3d0b..9d895570ceba05 100644
+--- a/fs/nfsd/export.h
++++ b/fs/nfsd/export.h
+@@ -75,7 +75,7 @@ struct svc_export {
+ u32 ex_layout_types;
+ struct nfsd4_deviceid_map *ex_devid_map;
+ struct cache_detail *cd;
+- struct rcu_head ex_rcu;
++ struct rcu_work ex_rcu_work;
+ unsigned long ex_xprtsec_modes;
+ struct export_stats *ex_stats;
+ };
+@@ -92,7 +92,7 @@ struct svc_expkey {
+ u32 ek_fsid[6];
+
+ struct path ek_path;
+- struct rcu_head ek_rcu;
++ struct rcu_work ek_rcu_work;
+ };
+
+ #define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 4039ffcf90ba58..49a49529c6b8fb 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -297,17 +297,17 @@ static int decode_cb_compound4res(struct xdr_stream *xdr,
+ u32 length;
+ __be32 *p;
+
+- p = xdr_inline_decode(xdr, 4 + 4);
++ p = xdr_inline_decode(xdr, XDR_UNIT);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+- hdr->status = be32_to_cpup(p++);
++ hdr->status = be32_to_cpup(p);
+ /* Ignore the tag */
+- length = be32_to_cpup(p++);
+- p = xdr_inline_decode(xdr, length + 4);
+- if (unlikely(p == NULL))
++ if (xdr_stream_decode_u32(xdr, &length) < 0)
++ goto out_overflow;
++ if (xdr_inline_decode(xdr, length) == NULL)
++ goto out_overflow;
++ if (xdr_stream_decode_u32(xdr, &hdr->nops) < 0)
+ goto out_overflow;
+- p += XDR_QUADLEN(length);
+- hdr->nops = be32_to_cpup(p);
+ return 0;
+ out_overflow:
+ return -EIO;
+@@ -1379,6 +1379,8 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
+ ses = c->cn_session;
+ }
+ spin_unlock(&clp->cl_lock);
++ if (!c)
++ return;
+
+ err = setup_callback_client(clp, &conn, ses);
+ if (err) {
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index d64f792964e1a5..b3eca08f15b13e 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1285,7 +1285,7 @@ static void nfsd4_stop_copy(struct nfsd4_copy *copy)
+ nfs4_put_copy(copy);
+ }
+
+-static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp)
++static struct nfsd4_copy *nfsd4_unhash_copy(struct nfs4_client *clp)
+ {
+ struct nfsd4_copy *copy = NULL;
+
+@@ -1294,6 +1294,9 @@ static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp)
+ copy = list_first_entry(&clp->async_copies, struct nfsd4_copy,
+ copies);
+ refcount_inc(&copy->refcount);
++ copy->cp_clp = NULL;
++ if (!list_empty(&copy->copies))
++ list_del_init(&copy->copies);
+ }
+ spin_unlock(&clp->async_lock);
+ return copy;
+@@ -1303,7 +1306,7 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp)
+ {
+ struct nfsd4_copy *copy;
+
+- while ((copy = nfsd4_get_copy(clp)) != NULL)
++ while ((copy = nfsd4_unhash_copy(clp)) != NULL)
+ nfsd4_stop_copy(copy);
+ }
+ #ifdef CONFIG_NFSD_V4_2_INTER_SSC
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index 4395577825a7fa..892fecce18b802 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -658,7 +658,8 @@ nfs4_reset_recoverydir(char *recdir)
+ return status;
+ status = -ENOTDIR;
+ if (d_is_dir(path.dentry)) {
+- strcpy(user_recovery_dirname, recdir);
++ strscpy(user_recovery_dirname, recdir,
++ sizeof(user_recovery_dirname));
+ status = 0;
+ }
+ path_put(&path);
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 901fc68636cd59..a25cb2ff1b0b64 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1625,6 +1625,14 @@ static void release_open_stateid(struct nfs4_ol_stateid *stp)
+ free_ol_stateid_reaplist(&reaplist);
+ }
+
++static bool nfs4_openowner_unhashed(struct nfs4_openowner *oo)
++{
++ lockdep_assert_held(&oo->oo_owner.so_client->cl_lock);
++
++ return list_empty(&oo->oo_owner.so_strhash) &&
++ list_empty(&oo->oo_perclient);
++}
++
+ static void unhash_openowner_locked(struct nfs4_openowner *oo)
+ {
+ struct nfs4_client *clp = oo->oo_owner.so_client;
+@@ -4632,6 +4640,12 @@ init_open_stateid(struct nfs4_file *fp, struct nfsd4_open *open)
+ spin_lock(&oo->oo_owner.so_client->cl_lock);
+ spin_lock(&fp->fi_lock);
+
++ if (nfs4_openowner_unhashed(oo)) {
++ mutex_unlock(&stp->st_mutex);
++ stp = NULL;
++ goto out_unlock;
++ }
++
+ retstp = nfsd4_find_existing_open(fp, open);
+ if (retstp)
+ goto out_unlock;
+@@ -5751,6 +5765,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
+
+ if (!stp) {
+ stp = init_open_stateid(fp, open);
++ if (!stp) {
++ status = nfserr_jukebox;
++ goto out;
++ }
++
+ if (!open->op_stp)
+ new_stp = true;
+ }
+diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
+index b5d8f238fce42a..9cc4ebb5350464 100644
+--- a/fs/notify/fsnotify.c
++++ b/fs/notify/fsnotify.c
+@@ -310,16 +310,19 @@ static int fsnotify_handle_event(struct fsnotify_group *group, __u32 mask,
+ if (!inode_mark)
+ return 0;
+
+- if (mask & FS_EVENT_ON_CHILD) {
+- /*
+- * Some events can be sent on both parent dir and child marks
+- * (e.g. FS_ATTRIB). If both parent dir and child are
+- * watching, report the event once to parent dir with name (if
+- * interested) and once to child without name (if interested).
+- * The child watcher is expecting an event without a file name
+- * and without the FS_EVENT_ON_CHILD flag.
+- */
+- mask &= ~FS_EVENT_ON_CHILD;
++ /*
++ * Some events can be sent on both parent dir and child marks (e.g.
++ * FS_ATTRIB). If both parent dir and child are watching, report the
++ * event once to parent dir with name (if interested) and once to child
++ * without name (if interested).
++ *
++ * In any case regardless whether the parent is watching or not, the
++ * child watcher is expecting an event without the FS_EVENT_ON_CHILD
++ * flag. The file name is expected if and only if this is a directory
++ * event.
++ */
++ mask &= ~FS_EVENT_ON_CHILD;
++ if (!(mask & ALL_FSNOTIFY_DIRENT_EVENTS)) {
+ dir = NULL;
+ name = NULL;
+ }
+diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
+index 3a520117fa59f0..a9ce7947228c8d 100644
+--- a/fs/ocfs2/aops.h
++++ b/fs/ocfs2/aops.h
+@@ -70,6 +70,8 @@ enum ocfs2_iocb_lock_bits {
+ OCFS2_IOCB_NUM_LOCKS
+ };
+
++#define ocfs2_iocb_init_rw_locked(iocb) \
++ (iocb->private = NULL)
+ #define ocfs2_iocb_clear_rw_locked(iocb) \
+ clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)
+ #define ocfs2_iocb_rw_locked_level(iocb) \
+diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
+index e4acb795d11901..0585f281ff62f0 100644
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -2397,6 +2397,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
+ } else
+ inode_lock(inode);
+
++ ocfs2_iocb_init_rw_locked(iocb);
++
+ /*
+ * Concurrent O_DIRECT writes are allowed with
+ * mount_option "coherency=buffered".
+@@ -2543,6 +2545,8 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,
+ if (!direct_io && nowait)
+ return -EOPNOTSUPP;
+
++ ocfs2_iocb_init_rw_locked(iocb);
++
+ /*
+ * buffered reads protect themselves in ->read_folio(). O_DIRECT reads
+ * need locks to protect pending reads from racing with truncate.
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index fca29dba7b146a..9c42a30317d587 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -741,8 +741,13 @@ static int ovl_security_fileattr(const struct path *realpath, struct fileattr *f
+ struct file *file;
+ unsigned int cmd;
+ int err;
++ unsigned int flags;
++
++ flags = O_RDONLY;
++ if (force_o_largefile())
++ flags |= O_LARGEFILE;
+
+- file = dentry_open(realpath, O_RDONLY, current_cred());
++ file = dentry_open(realpath, flags, current_cred());
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
+index 89e0d60d35b6cf..0bf3ffcd072f6a 100644
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -171,6 +171,9 @@ void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
+
+ bool ovl_dentry_weird(struct dentry *dentry)
+ {
++ if (!d_can_lookup(dentry) && !d_is_file(dentry) && !d_is_symlink(dentry))
++ return true;
++
+ return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT |
+ DCACHE_MANAGE_TRANSIT |
+ DCACHE_OP_HASH |
+diff --git a/fs/proc/array.c b/fs/proc/array.c
+index 37b8061d84bb79..34a47fb0c57f25 100644
+--- a/fs/proc/array.c
++++ b/fs/proc/array.c
+@@ -477,13 +477,13 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
+ int permitted;
+ struct mm_struct *mm;
+ unsigned long long start_time;
+- unsigned long cmin_flt = 0, cmaj_flt = 0;
+- unsigned long min_flt = 0, maj_flt = 0;
+- u64 cutime, cstime, utime, stime;
+- u64 cgtime, gtime;
++ unsigned long cmin_flt, cmaj_flt, min_flt, maj_flt;
++ u64 cutime, cstime, cgtime, utime, stime, gtime;
+ unsigned long rsslim = 0;
+ unsigned long flags;
+ int exit_code = task->exit_code;
++ struct signal_struct *sig = task->signal;
++ unsigned int seq = 1;
+
+ state = *get_task_state(task);
+ vsize = eip = esp = 0;
+@@ -511,12 +511,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
+
+ sigemptyset(&sigign);
+ sigemptyset(&sigcatch);
+- cutime = cstime = 0;
+- cgtime = gtime = 0;
+
+ if (lock_task_sighand(task, &flags)) {
+- struct signal_struct *sig = task->signal;
+-
+ if (sig->tty) {
+ struct pid *pgrp = tty_get_pgrp(sig->tty);
+ tty_pgrp = pid_nr_ns(pgrp, ns);
+@@ -527,26 +523,9 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
+ num_threads = get_nr_threads(task);
+ collect_sigign_sigcatch(task, &sigign, &sigcatch);
+
+- cmin_flt = sig->cmin_flt;
+- cmaj_flt = sig->cmaj_flt;
+- cutime = sig->cutime;
+- cstime = sig->cstime;
+- cgtime = sig->cgtime;
+ rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
+
+- /* add up live thread stats at the group level */
+ if (whole) {
+- struct task_struct *t = task;
+- do {
+- min_flt += t->min_flt;
+- maj_flt += t->maj_flt;
+- gtime += task_gtime(t);
+- } while_each_thread(task, t);
+-
+- min_flt += sig->min_flt;
+- maj_flt += sig->maj_flt;
+- gtime += sig->gtime;
+-
+ if (sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_STOP_STOPPED))
+ exit_code = sig->group_exit_code;
+ }
+@@ -561,6 +540,34 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
+ if (permitted && (!whole || num_threads < 2))
+ wchan = !task_is_running(task);
+
++ do {
++ seq++; /* 2 on the 1st/lockless path, otherwise odd */
++ flags = read_seqbegin_or_lock_irqsave(&sig->stats_lock, &seq);
++
++ cmin_flt = sig->cmin_flt;
++ cmaj_flt = sig->cmaj_flt;
++ cutime = sig->cutime;
++ cstime = sig->cstime;
++ cgtime = sig->cgtime;
++
++ if (whole) {
++ struct task_struct *t;
++
++ min_flt = sig->min_flt;
++ maj_flt = sig->maj_flt;
++ gtime = sig->gtime;
++
++ rcu_read_lock();
++ __for_each_thread(sig, t) {
++ min_flt += t->min_flt;
++ maj_flt += t->maj_flt;
++ gtime += task_gtime(t);
++ }
++ rcu_read_unlock();
++ }
++ } while (need_seqretry(&sig->stats_lock, seq));
++ done_seqretry_irqrestore(&sig->stats_lock, seq, flags);
++
+ if (whole) {
+ thread_group_cputime_adjusted(task, &utime, &stime);
+ } else {
+diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
+index 7e4fa9c68c1dd0..1127457d0fcb37 100644
+--- a/fs/proc/kcore.c
++++ b/fs/proc/kcore.c
+@@ -493,13 +493,13 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
+ * the previous entry, search for a matching entry.
+ */
+ if (!m || start < m->addr || start >= m->addr + m->size) {
+- struct kcore_list *iter;
++ struct kcore_list *pos;
+
+ m = NULL;
+- list_for_each_entry(iter, &kclist_head, list) {
+- if (start >= iter->addr &&
+- start < iter->addr + iter->size) {
+- m = iter;
++ list_for_each_entry(pos, &kclist_head, list) {
++ if (start >= pos->addr &&
++ start < pos->addr + pos->size) {
++ m = pos;
+ break;
+ }
+ }
+@@ -599,6 +599,7 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
+ ret = -EFAULT;
+ goto out;
+ }
++ ret = 0;
+ /*
+ * We know the bounce buffer is safe to copy from, so
+ * use _copy_to_iter() directly.
+diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c
+index f4616083faef3b..04bb29721419b0 100644
+--- a/fs/proc/softirqs.c
++++ b/fs/proc/softirqs.c
+@@ -20,7 +20,7 @@ static int show_softirqs(struct seq_file *p, void *v)
+ for (i = 0; i < NR_SOFTIRQS; i++) {
+ seq_printf(p, "%12s:", softirq_to_name[i]);
+ for_each_possible_cpu(j)
+- seq_printf(p, " %10u", kstat_softirqs_cpu(i, j));
++ seq_put_decimal_ull_width(p, " ", kstat_softirqs_cpu(i, j), 10);
+ seq_putc(p, '\n');
+ }
+ return 0;
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 23dbde1de25205..67562c78e57d53 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -690,6 +690,8 @@ int dquot_writeback_dquots(struct super_block *sb, int type)
+
+ WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount));
+
++ flush_delayed_work(&quota_release_work);
++
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ if (type != -1 && cnt != type)
+ continue;
+diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
+index 0ff2491c311d8a..9c0ef4195b5829 100644
+--- a/fs/smb/client/cached_dir.c
++++ b/fs/smb/client/cached_dir.c
+@@ -17,6 +17,11 @@ static void free_cached_dir(struct cached_fid *cfid);
+ static void smb2_close_cached_fid(struct kref *ref);
+ static void cfids_laundromat_worker(struct work_struct *work);
+
++struct cached_dir_dentry {
++ struct list_head entry;
++ struct dentry *dentry;
++};
++
+ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
+ const char *path,
+ bool lookup_only,
+@@ -59,6 +64,16 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
+ list_add(&cfid->entry, &cfids->entries);
+ cfid->on_list = true;
+ kref_get(&cfid->refcount);
++ /*
++ * Set @cfid->has_lease to true during construction so that the lease
++ * reference can be put in cached_dir_lease_break() due to a potential
++ * lease break right after the request is sent or while @cfid is still
++ * being cached, or if a reconnection is triggered during construction.
++ * Concurrent processes won't be to use it yet due to @cfid->time being
++ * zero.
++ */
++ cfid->has_lease = true;
++
+ spin_unlock(&cfids->cfid_list_lock);
+ return cfid;
+ }
+@@ -176,12 +191,12 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+ return -ENOENT;
+ }
+ /*
+- * Return cached fid if it has a lease. Otherwise, it is either a new
+- * entry or laundromat worker removed it from @cfids->entries. Caller
+- * will put last reference if the latter.
++ * Return cached fid if it is valid (has a lease and has a time).
++ * Otherwise, it is either a new entry or laundromat worker removed it
++ * from @cfids->entries. Caller will put last reference if the latter.
+ */
+ spin_lock(&cfids->cfid_list_lock);
+- if (cfid->has_lease) {
++ if (cfid->has_lease && cfid->time) {
+ spin_unlock(&cfids->cfid_list_lock);
+ *ret_cfid = cfid;
+ kfree(utf16_path);
+@@ -212,6 +227,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+ }
+ }
+ cfid->dentry = dentry;
++ cfid->tcon = tcon;
+
+ /*
+ * We do not hold the lock for the open because in case
+@@ -267,15 +283,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+
+ smb2_set_related(&rqst[1]);
+
+- /*
+- * Set @cfid->has_lease to true before sending out compounded request so
+- * its lease reference can be put in cached_dir_lease_break() due to a
+- * potential lease break right after the request is sent or while @cfid
+- * is still being cached. Concurrent processes won't be to use it yet
+- * due to @cfid->time being zero.
+- */
+- cfid->has_lease = true;
+-
+ if (retries) {
+ smb2_set_replay(server, &rqst[0]);
+ smb2_set_replay(server, &rqst[1]);
+@@ -292,7 +299,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+ }
+ goto oshr_free;
+ }
+- cfid->tcon = tcon;
+ cfid->is_open = true;
+
+ spin_lock(&cfids->cfid_list_lock);
+@@ -347,6 +353,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+ SMB2_query_info_free(&rqst[1]);
+ free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
+ free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
++out:
+ if (rc) {
+ spin_lock(&cfids->cfid_list_lock);
+ if (cfid->on_list) {
+@@ -358,23 +365,14 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+ /*
+ * We are guaranteed to have two references at this
+ * point. One for the caller and one for a potential
+- * lease. Release the Lease-ref so that the directory
+- * will be closed when the caller closes the cached
+- * handle.
++ * lease. Release one here, and the second below.
+ */
+ cfid->has_lease = false;
+- spin_unlock(&cfids->cfid_list_lock);
+ kref_put(&cfid->refcount, smb2_close_cached_fid);
+- goto out;
+ }
+ spin_unlock(&cfids->cfid_list_lock);
+- }
+-out:
+- if (rc) {
+- if (cfid->is_open)
+- SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
+- cfid->fid.volatile_fid);
+- free_cached_dir(cfid);
++
++ kref_put(&cfid->refcount, smb2_close_cached_fid);
+ } else {
+ *ret_cfid = cfid;
+ atomic_inc(&tcon->num_remote_opens);
+@@ -401,7 +399,7 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
+ spin_lock(&cfids->cfid_list_lock);
+ list_for_each_entry(cfid, &cfids->entries, entry) {
+ if (dentry && cfid->dentry == dentry) {
+- cifs_dbg(FYI, "found a cached root file handle by dentry\n");
++ cifs_dbg(FYI, "found a cached file handle by dentry\n");
+ kref_get(&cfid->refcount);
+ *ret_cfid = cfid;
+ spin_unlock(&cfids->cfid_list_lock);
+@@ -477,7 +475,10 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
+ struct cifs_tcon *tcon;
+ struct tcon_link *tlink;
+ struct cached_fids *cfids;
++ struct cached_dir_dentry *tmp_list, *q;
++ LIST_HEAD(entry);
+
++ spin_lock(&cifs_sb->tlink_tree_lock);
+ for (node = rb_first(root); node; node = rb_next(node)) {
+ tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+ tcon = tlink_tcon(tlink);
+@@ -486,11 +487,30 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
+ cfids = tcon->cfids;
+ if (cfids == NULL)
+ continue;
++ spin_lock(&cfids->cfid_list_lock);
+ list_for_each_entry(cfid, &cfids->entries, entry) {
+- dput(cfid->dentry);
++ tmp_list = kmalloc(sizeof(*tmp_list), GFP_ATOMIC);
++ if (tmp_list == NULL)
++ break;
++ spin_lock(&cfid->fid_lock);
++ tmp_list->dentry = cfid->dentry;
+ cfid->dentry = NULL;
++ spin_unlock(&cfid->fid_lock);
++
++ list_add_tail(&tmp_list->entry, &entry);
+ }
++ spin_unlock(&cfids->cfid_list_lock);
++ }
++ spin_unlock(&cifs_sb->tlink_tree_lock);
++
++ list_for_each_entry_safe(tmp_list, q, &entry, entry) {
++ list_del(&tmp_list->entry);
++ dput(tmp_list->dentry);
++ kfree(tmp_list);
+ }
++
++ /* Flush any pending work that will drop dentries */
++ flush_workqueue(cfid_put_wq);
+ }
+
+ /*
+@@ -501,50 +521,71 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
+ {
+ struct cached_fids *cfids = tcon->cfids;
+ struct cached_fid *cfid, *q;
+- LIST_HEAD(entry);
+
+ if (cfids == NULL)
+ return;
+
++ /*
++ * Mark all the cfids as closed, and move them to the cfids->dying list.
++ * They'll be cleaned up later by cfids_invalidation_worker. Take
++ * a reference to each cfid during this process.
++ */
+ spin_lock(&cfids->cfid_list_lock);
+ list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
+- list_move(&cfid->entry, &entry);
++ list_move(&cfid->entry, &cfids->dying);
+ cfids->num_entries--;
+ cfid->is_open = false;
+ cfid->on_list = false;
+- /* To prevent race with smb2_cached_lease_break() */
+- kref_get(&cfid->refcount);
+- }
+- spin_unlock(&cfids->cfid_list_lock);
+-
+- list_for_each_entry_safe(cfid, q, &entry, entry) {
+- list_del(&cfid->entry);
+- cancel_work_sync(&cfid->lease_break);
+ if (cfid->has_lease) {
+ /*
+- * We lease was never cancelled from the server so we
+- * need to drop the reference.
++ * The lease was never cancelled from the server,
++ * so steal that reference.
+ */
+- spin_lock(&cfids->cfid_list_lock);
+ cfid->has_lease = false;
+- spin_unlock(&cfids->cfid_list_lock);
+- kref_put(&cfid->refcount, smb2_close_cached_fid);
+- }
+- /* Drop the extra reference opened above*/
+- kref_put(&cfid->refcount, smb2_close_cached_fid);
++ } else
++ kref_get(&cfid->refcount);
+ }
++ /*
++ * Queue dropping of the dentries once locks have been dropped
++ */
++ if (!list_empty(&cfids->dying))
++ queue_work(cfid_put_wq, &cfids->invalidation_work);
++ spin_unlock(&cfids->cfid_list_lock);
+ }
+
+ static void
+-smb2_cached_lease_break(struct work_struct *work)
++cached_dir_offload_close(struct work_struct *work)
+ {
+ struct cached_fid *cfid = container_of(work,
+- struct cached_fid, lease_break);
++ struct cached_fid, close_work);
++ struct cifs_tcon *tcon = cfid->tcon;
++
++ WARN_ON(cfid->on_list);
+
+- spin_lock(&cfid->cfids->cfid_list_lock);
+- cfid->has_lease = false;
+- spin_unlock(&cfid->cfids->cfid_list_lock);
+ kref_put(&cfid->refcount, smb2_close_cached_fid);
++ cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close);
++}
++
++/*
++ * Release the cached directory's dentry, and then queue work to drop cached
++ * directory itself (closing on server if needed).
++ *
++ * Must be called with a reference to the cached_fid and a reference to the
++ * tcon.
++ */
++static void cached_dir_put_work(struct work_struct *work)
++{
++ struct cached_fid *cfid = container_of(work, struct cached_fid,
++ put_work);
++ struct dentry *dentry;
++
++ spin_lock(&cfid->fid_lock);
++ dentry = cfid->dentry;
++ cfid->dentry = NULL;
++ spin_unlock(&cfid->fid_lock);
++
++ dput(dentry);
++ queue_work(serverclose_wq, &cfid->close_work);
+ }
+
+ int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
+@@ -561,6 +602,7 @@ int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
+ !memcmp(lease_key,
+ cfid->fid.lease_key,
+ SMB2_LEASE_KEY_SIZE)) {
++ cfid->has_lease = false;
+ cfid->time = 0;
+ /*
+ * We found a lease remove it from the list
+@@ -570,8 +612,10 @@ int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
+ cfid->on_list = false;
+ cfids->num_entries--;
+
+- queue_work(cifsiod_wq,
+- &cfid->lease_break);
++ ++tcon->tc_count;
++ trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
++ netfs_trace_tcon_ref_get_cached_lease_break);
++ queue_work(cfid_put_wq, &cfid->put_work);
+ spin_unlock(&cfids->cfid_list_lock);
+ return true;
+ }
+@@ -593,7 +637,8 @@ static struct cached_fid *init_cached_dir(const char *path)
+ return NULL;
+ }
+
+- INIT_WORK(&cfid->lease_break, smb2_cached_lease_break);
++ INIT_WORK(&cfid->close_work, cached_dir_offload_close);
++ INIT_WORK(&cfid->put_work, cached_dir_put_work);
+ INIT_LIST_HEAD(&cfid->entry);
+ INIT_LIST_HEAD(&cfid->dirents.entries);
+ mutex_init(&cfid->dirents.de_mutex);
+@@ -606,6 +651,9 @@ static void free_cached_dir(struct cached_fid *cfid)
+ {
+ struct cached_dirent *dirent, *q;
+
++ WARN_ON(work_pending(&cfid->close_work));
++ WARN_ON(work_pending(&cfid->put_work));
++
+ dput(cfid->dentry);
+ cfid->dentry = NULL;
+
+@@ -623,10 +671,30 @@ static void free_cached_dir(struct cached_fid *cfid)
+ kfree(cfid);
+ }
+
++static void cfids_invalidation_worker(struct work_struct *work)
++{
++ struct cached_fids *cfids = container_of(work, struct cached_fids,
++ invalidation_work);
++ struct cached_fid *cfid, *q;
++ LIST_HEAD(entry);
++
++ spin_lock(&cfids->cfid_list_lock);
++ /* move cfids->dying to the local list */
++ list_cut_before(&entry, &cfids->dying, &cfids->dying);
++ spin_unlock(&cfids->cfid_list_lock);
++
++ list_for_each_entry_safe(cfid, q, &entry, entry) {
++ list_del(&cfid->entry);
++ /* Drop the ref-count acquired in invalidate_all_cached_dirs */
++ kref_put(&cfid->refcount, smb2_close_cached_fid);
++ }
++}
++
+ static void cfids_laundromat_worker(struct work_struct *work)
+ {
+ struct cached_fids *cfids;
+ struct cached_fid *cfid, *q;
++ struct dentry *dentry;
+ LIST_HEAD(entry);
+
+ cfids = container_of(work, struct cached_fids, laundromat_work.work);
+@@ -638,33 +706,42 @@ static void cfids_laundromat_worker(struct work_struct *work)
+ cfid->on_list = false;
+ list_move(&cfid->entry, &entry);
+ cfids->num_entries--;
+- /* To prevent race with smb2_cached_lease_break() */
+- kref_get(&cfid->refcount);
++ if (cfid->has_lease) {
++ /*
++ * Our lease has not yet been cancelled from the
++ * server. Steal that reference.
++ */
++ cfid->has_lease = false;
++ } else
++ kref_get(&cfid->refcount);
+ }
+ }
+ spin_unlock(&cfids->cfid_list_lock);
+
+ list_for_each_entry_safe(cfid, q, &entry, entry) {
+ list_del(&cfid->entry);
+- /*
+- * Cancel and wait for the work to finish in case we are racing
+- * with it.
+- */
+- cancel_work_sync(&cfid->lease_break);
+- if (cfid->has_lease) {
++
++ spin_lock(&cfid->fid_lock);
++ dentry = cfid->dentry;
++ cfid->dentry = NULL;
++ spin_unlock(&cfid->fid_lock);
++
++ dput(dentry);
++ if (cfid->is_open) {
++ spin_lock(&cifs_tcp_ses_lock);
++ ++cfid->tcon->tc_count;
++ trace_smb3_tcon_ref(cfid->tcon->debug_id, cfid->tcon->tc_count,
++ netfs_trace_tcon_ref_get_cached_laundromat);
++ spin_unlock(&cifs_tcp_ses_lock);
++ queue_work(serverclose_wq, &cfid->close_work);
++ } else
+ /*
+- * Our lease has not yet been cancelled from the server
+- * so we need to drop the reference.
++ * Drop the ref-count from above, either the lease-ref (if there
++ * was one) or the extra one acquired.
+ */
+- spin_lock(&cfids->cfid_list_lock);
+- cfid->has_lease = false;
+- spin_unlock(&cfids->cfid_list_lock);
+ kref_put(&cfid->refcount, smb2_close_cached_fid);
+- }
+- /* Drop the extra reference opened above */
+- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ }
+- queue_delayed_work(cifsiod_wq, &cfids->laundromat_work,
++ queue_delayed_work(cfid_put_wq, &cfids->laundromat_work,
+ dir_cache_timeout * HZ);
+ }
+
+@@ -677,9 +754,11 @@ struct cached_fids *init_cached_dirs(void)
+ return NULL;
+ spin_lock_init(&cfids->cfid_list_lock);
+ INIT_LIST_HEAD(&cfids->entries);
++ INIT_LIST_HEAD(&cfids->dying);
+
++ INIT_WORK(&cfids->invalidation_work, cfids_invalidation_worker);
+ INIT_DELAYED_WORK(&cfids->laundromat_work, cfids_laundromat_worker);
+- queue_delayed_work(cifsiod_wq, &cfids->laundromat_work,
++ queue_delayed_work(cfid_put_wq, &cfids->laundromat_work,
+ dir_cache_timeout * HZ);
+
+ return cfids;
+@@ -698,6 +777,7 @@ void free_cached_dirs(struct cached_fids *cfids)
+ return;
+
+ cancel_delayed_work_sync(&cfids->laundromat_work);
++ cancel_work_sync(&cfids->invalidation_work);
+
+ spin_lock(&cfids->cfid_list_lock);
+ list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
+@@ -705,6 +785,11 @@ void free_cached_dirs(struct cached_fids *cfids)
+ cfid->is_open = false;
+ list_move(&cfid->entry, &entry);
+ }
++ list_for_each_entry_safe(cfid, q, &cfids->dying, entry) {
++ cfid->on_list = false;
++ cfid->is_open = false;
++ list_move(&cfid->entry, &entry);
++ }
+ spin_unlock(&cfids->cfid_list_lock);
+
+ list_for_each_entry_safe(cfid, q, &entry, entry) {
+diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
+index 81ba0fd5cc16d6..1dfe79d947a62f 100644
+--- a/fs/smb/client/cached_dir.h
++++ b/fs/smb/client/cached_dir.h
+@@ -44,7 +44,8 @@ struct cached_fid {
+ spinlock_t fid_lock;
+ struct cifs_tcon *tcon;
+ struct dentry *dentry;
+- struct work_struct lease_break;
++ struct work_struct put_work;
++ struct work_struct close_work;
+ struct smb2_file_all_info file_all_info;
+ struct cached_dirents dirents;
+ };
+@@ -53,10 +54,13 @@ struct cached_fid {
+ struct cached_fids {
+ /* Must be held when:
+ * - accessing the cfids->entries list
++ * - accessing the cfids->dying list
+ */
+ spinlock_t cfid_list_lock;
+ int num_entries;
+ struct list_head entries;
++ struct list_head dying;
++ struct work_struct invalidation_work;
+ struct delayed_work laundromat_work;
+ };
+
+diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
+index 2d9f8bdb6d4efe..6ed0f2548232f9 100644
+--- a/fs/smb/client/cifsfs.c
++++ b/fs/smb/client/cifsfs.c
+@@ -156,6 +156,7 @@ struct workqueue_struct *fileinfo_put_wq;
+ struct workqueue_struct *cifsoplockd_wq;
+ struct workqueue_struct *deferredclose_wq;
+ struct workqueue_struct *serverclose_wq;
++struct workqueue_struct *cfid_put_wq;
+ __u32 cifs_lock_secret;
+
+ /*
+@@ -1899,9 +1900,16 @@ init_cifs(void)
+ goto out_destroy_deferredclose_wq;
+ }
+
++ cfid_put_wq = alloc_workqueue("cfid_put_wq",
++ WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
++ if (!cfid_put_wq) {
++ rc = -ENOMEM;
++ goto out_destroy_serverclose_wq;
++ }
++
+ rc = cifs_init_inodecache();
+ if (rc)
+- goto out_destroy_serverclose_wq;
++ goto out_destroy_cfid_put_wq;
+
+ rc = init_mids();
+ if (rc)
+@@ -1963,6 +1971,8 @@ init_cifs(void)
+ destroy_mids();
+ out_destroy_inodecache:
+ cifs_destroy_inodecache();
++out_destroy_cfid_put_wq:
++ destroy_workqueue(cfid_put_wq);
+ out_destroy_serverclose_wq:
+ destroy_workqueue(serverclose_wq);
+ out_destroy_deferredclose_wq:
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 111540eff66e7d..6b57b167a49d80 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -592,6 +592,7 @@ struct smb_version_operations {
+ /* Check for STATUS_NETWORK_NAME_DELETED */
+ bool (*is_network_name_deleted)(char *buf, struct TCP_Server_Info *srv);
+ int (*parse_reparse_point)(struct cifs_sb_info *cifs_sb,
++ const char *full_path,
+ struct kvec *rsp_iov,
+ struct cifs_open_info_data *data);
+ int (*create_reparse_symlink)(const unsigned int xid,
+@@ -2022,7 +2023,7 @@ require use of the stronger protocol */
+ * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once
+ * ->can_cache_brlcks
+ * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc
+- * cached_fid->fid_mutex cifs_tcon->crfid tcon_info_alloc
++ * cached_fids->cfid_list_lock cifs_tcon->cfids->entries init_cached_dirs
+ * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo
+ * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo
+ * ->invalidHandle initiate_cifs_search
+@@ -2111,6 +2112,7 @@ extern struct workqueue_struct *fileinfo_put_wq;
+ extern struct workqueue_struct *cifsoplockd_wq;
+ extern struct workqueue_struct *deferredclose_wq;
+ extern struct workqueue_struct *serverclose_wq;
++extern struct workqueue_struct *cfid_put_wq;
+ extern __u32 cifs_lock_secret;
+
+ extern mempool_t *cifs_sm_req_poolp;
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index fbc358c09da3b1..fa7901ad3b80b4 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -679,6 +679,7 @@ char *extract_hostname(const char *unc);
+ char *extract_sharename(const char *unc);
+ int parse_reparse_point(struct reparse_data_buffer *buf,
+ u32 plen, struct cifs_sb_info *cifs_sb,
++ const char *full_path,
+ bool unicode, struct cifs_open_info_data *data);
+ int cifs_sfu_make_node(unsigned int xid, struct inode *inode,
+ struct dentry *dentry, struct cifs_tcon *tcon,
+diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
+index 1df0a6edcc2167..7b850c40b2f320 100644
+--- a/fs/smb/client/connect.c
++++ b/fs/smb/client/connect.c
+@@ -1908,11 +1908,35 @@ static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+ CIFS_MAX_USERNAME_LEN))
+ return 0;
+ if ((ctx->username && strlen(ctx->username) != 0) &&
+- ses->password != NULL &&
+- strncmp(ses->password,
+- ctx->password ? ctx->password : "",
+- CIFS_MAX_PASSWORD_LEN))
+- return 0;
++ ses->password != NULL) {
++
++ /* New mount can only share sessions with an existing mount if:
++ * 1. Both password and password2 match, or
++ * 2. password2 of the old mount matches password of the new mount
++ * and password of the old mount matches password2 of the new
++ * mount
++ */
++ if (ses->password2 != NULL && ctx->password2 != NULL) {
++ if (!((strncmp(ses->password, ctx->password ?
++ ctx->password : "", CIFS_MAX_PASSWORD_LEN) == 0 &&
++ strncmp(ses->password2, ctx->password2,
++ CIFS_MAX_PASSWORD_LEN) == 0) ||
++ (strncmp(ses->password, ctx->password2,
++ CIFS_MAX_PASSWORD_LEN) == 0 &&
++ strncmp(ses->password2, ctx->password ?
++ ctx->password : "", CIFS_MAX_PASSWORD_LEN) == 0)))
++ return 0;
++
++ } else if ((ses->password2 == NULL && ctx->password2 != NULL) ||
++ (ses->password2 != NULL && ctx->password2 == NULL)) {
++ return 0;
++
++ } else {
++ if (strncmp(ses->password, ctx->password ?
++ ctx->password : "", CIFS_MAX_PASSWORD_LEN))
++ return 0;
++ }
++ }
+ }
+
+ if (strcmp(ctx->local_nls->charset, ses->local_nls->charset))
+@@ -2256,6 +2280,7 @@ struct cifs_ses *
+ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ {
+ int rc = 0;
++ int retries = 0;
+ unsigned int xid;
+ struct cifs_ses *ses;
+ struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
+@@ -2274,6 +2299,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ cifs_dbg(FYI, "Session needs reconnect\n");
+
+ mutex_lock(&ses->session_mutex);
++
++retry_old_session:
+ rc = cifs_negotiate_protocol(xid, ses, server);
+ if (rc) {
+ mutex_unlock(&ses->session_mutex);
+@@ -2286,6 +2313,13 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ rc = cifs_setup_session(xid, ses, server,
+ ctx->local_nls);
+ if (rc) {
++ if (((rc == -EACCES) || (rc == -EKEYEXPIRED) ||
++ (rc == -EKEYREVOKED)) && !retries && ses->password2) {
++ retries++;
++ cifs_dbg(FYI, "Session reconnect failed, retrying with alternate password\n");
++ swap(ses->password, ses->password2);
++ goto retry_old_session;
++ }
+ mutex_unlock(&ses->session_mutex);
+ /* problem -- put our reference */
+ cifs_put_smb_ses(ses);
+@@ -2361,6 +2395,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ ses->chans_need_reconnect = 1;
+ spin_unlock(&ses->chan_lock);
+
++retry_new_session:
+ mutex_lock(&ses->session_mutex);
+ rc = cifs_negotiate_protocol(xid, ses, server);
+ if (!rc)
+@@ -2373,8 +2408,16 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ sizeof(ses->smb3signingkey));
+ spin_unlock(&ses->chan_lock);
+
+- if (rc)
+- goto get_ses_fail;
++ if (rc) {
++ if (((rc == -EACCES) || (rc == -EKEYEXPIRED) ||
++ (rc == -EKEYREVOKED)) && !retries && ses->password2) {
++ retries++;
++ cifs_dbg(FYI, "Session setup failed, retrying with alternate password\n");
++ swap(ses->password, ses->password2);
++ goto retry_new_session;
++ } else
++ goto get_ses_fail;
++ }
+
+ /*
+ * success, put it on the list and add it as first channel
+@@ -2558,7 +2601,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+
+ if (ses->server->dialect >= SMB20_PROT_ID &&
+ (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING))
+- nohandlecache = ctx->nohandlecache;
++ nohandlecache = ctx->nohandlecache || !dir_cache_timeout;
+ else
+ nohandlecache = true;
+ tcon = tcon_info_alloc(!nohandlecache, netfs_trace_tcon_ref_new);
+diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
+index 8d7484400fe8e1..4e77ba191ef87e 100644
+--- a/fs/smb/client/fs_context.c
++++ b/fs/smb/client/fs_context.c
+@@ -888,12 +888,37 @@ do { \
+ cifs_sb->ctx->field = NULL; \
+ } while (0)
+
++int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
++{
++ if (ses->password &&
++ cifs_sb->ctx->password &&
++ strcmp(ses->password, cifs_sb->ctx->password)) {
++ kfree_sensitive(cifs_sb->ctx->password);
++ cifs_sb->ctx->password = kstrdup(ses->password, GFP_KERNEL);
++ if (!cifs_sb->ctx->password)
++ return -ENOMEM;
++ }
++ if (ses->password2 &&
++ cifs_sb->ctx->password2 &&
++ strcmp(ses->password2, cifs_sb->ctx->password2)) {
++ kfree_sensitive(cifs_sb->ctx->password2);
++ cifs_sb->ctx->password2 = kstrdup(ses->password2, GFP_KERNEL);
++ if (!cifs_sb->ctx->password2) {
++ kfree_sensitive(cifs_sb->ctx->password);
++ cifs_sb->ctx->password = NULL;
++ return -ENOMEM;
++ }
++ }
++ return 0;
++}
++
+ static int smb3_reconfigure(struct fs_context *fc)
+ {
+ struct smb3_fs_context *ctx = smb3_fc2context(fc);
+ struct dentry *root = fc->root;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
+ struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses;
++ char *new_password = NULL, *new_password2 = NULL;
+ bool need_recon = false;
+ int rc;
+
+@@ -913,21 +938,63 @@ static int smb3_reconfigure(struct fs_context *fc)
+ STEAL_STRING(cifs_sb, ctx, UNC);
+ STEAL_STRING(cifs_sb, ctx, source);
+ STEAL_STRING(cifs_sb, ctx, username);
++
+ if (need_recon == false)
+ STEAL_STRING_SENSITIVE(cifs_sb, ctx, password);
+ else {
+- kfree_sensitive(ses->password);
+- ses->password = kstrdup(ctx->password, GFP_KERNEL);
+- if (!ses->password)
+- return -ENOMEM;
+- kfree_sensitive(ses->password2);
+- ses->password2 = kstrdup(ctx->password2, GFP_KERNEL);
+- if (!ses->password2) {
+- kfree_sensitive(ses->password);
+- ses->password = NULL;
++ if (ctx->password) {
++ new_password = kstrdup(ctx->password, GFP_KERNEL);
++ if (!new_password)
++ return -ENOMEM;
++ } else
++ STEAL_STRING_SENSITIVE(cifs_sb, ctx, password);
++ }
++
++ /*
++ * if a new password2 has been specified, then reset it's value
++ * inside the ses struct
++ */
++ if (ctx->password2) {
++ new_password2 = kstrdup(ctx->password2, GFP_KERNEL);
++ if (!new_password2) {
++ kfree_sensitive(new_password);
+ return -ENOMEM;
+ }
++ } else
++ STEAL_STRING_SENSITIVE(cifs_sb, ctx, password2);
++
++ /*
++ * we may update the passwords in the ses struct below. Make sure we do
++ * not race with smb2_reconnect
++ */
++ mutex_lock(&ses->session_mutex);
++
++ /*
++ * smb2_reconnect may swap password and password2 in case session setup
++ * failed. First get ctx passwords in sync with ses passwords. It should
++ * be okay to do this even if this function were to return an error at a
++ * later stage
++ */
++ rc = smb3_sync_session_ctx_passwords(cifs_sb, ses);
++ if (rc) {
++ mutex_unlock(&ses->session_mutex);
++ return rc;
+ }
++
++ /*
++ * now that allocations for passwords are done, commit them
++ */
++ if (new_password) {
++ kfree_sensitive(ses->password);
++ ses->password = new_password;
++ }
++ if (new_password2) {
++ kfree_sensitive(ses->password2);
++ ses->password2 = new_password2;
++ }
++
++ mutex_unlock(&ses->session_mutex);
++
+ STEAL_STRING(cifs_sb, ctx, domainname);
+ STEAL_STRING(cifs_sb, ctx, nodename);
+ STEAL_STRING(cifs_sb, ctx, iocharset);
+diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h
+index cf577ec0dd0ac4..bbd2063ab838d3 100644
+--- a/fs/smb/client/fs_context.h
++++ b/fs/smb/client/fs_context.h
+@@ -298,6 +298,7 @@ static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *f
+ }
+
+ extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
++extern int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
+ extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
+
+ /*
+diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
+index e7970cbeb86111..0f73f0dc6deb36 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -1054,6 +1054,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
+ rc = 0;
+ } else if (iov && server->ops->parse_reparse_point) {
+ rc = server->ops->parse_reparse_point(cifs_sb,
++ full_path,
+ iov, data);
+ }
+ break;
+@@ -2412,13 +2413,10 @@ cifs_dentry_needs_reval(struct dentry *dentry)
+ return true;
+
+ if (!open_cached_dir_by_dentry(tcon, dentry->d_parent, &cfid)) {
+- spin_lock(&cfid->fid_lock);
+ if (cfid->time && cifs_i->time > cfid->time) {
+- spin_unlock(&cfid->fid_lock);
+ close_cached_dir(cfid);
+ return false;
+ }
+- spin_unlock(&cfid->fid_lock);
+ close_cached_dir(cfid);
+ }
+ /*
+diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
+index 74abbdf5026c73..f74d0a86f44a4e 100644
+--- a/fs/smb/client/reparse.c
++++ b/fs/smb/client/reparse.c
+@@ -35,6 +35,9 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
+ u16 len, plen;
+ int rc = 0;
+
++ if (strlen(symname) > REPARSE_SYM_PATH_MAX)
++ return -ENAMETOOLONG;
++
+ sym = kstrdup(symname, GFP_KERNEL);
+ if (!sym)
+ return -ENOMEM;
+@@ -64,7 +67,7 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
+ if (rc < 0)
+ goto out;
+
+- plen = 2 * UniStrnlen((wchar_t *)path, PATH_MAX);
++ plen = 2 * UniStrnlen((wchar_t *)path, REPARSE_SYM_PATH_MAX);
+ len = sizeof(*buf) + plen * 2;
+ buf = kzalloc(len, GFP_KERNEL);
+ if (!buf) {
+@@ -532,9 +535,76 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
+ return 0;
+ }
+
++int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
++ bool unicode, bool relative,
++ const char *full_path,
++ struct cifs_sb_info *cifs_sb)
++{
++ char sep = CIFS_DIR_SEP(cifs_sb);
++ char *linux_target = NULL;
++ char *smb_target = NULL;
++ int levels;
++ int rc;
++ int i;
++
++ smb_target = cifs_strndup_from_utf16(buf, len, unicode, cifs_sb->local_nls);
++ if (!smb_target) {
++ rc = -ENOMEM;
++ goto out;
++ }
++
++ if (smb_target[0] == sep && relative) {
++ /*
++ * This is a relative SMB symlink from the top of the share,
++ * which is the top level directory of the Linux mount point.
++ * Linux does not support such relative symlinks, so convert
++ * it to the relative symlink from the current directory.
++ * full_path is the SMB path to the symlink (from which is
++ * extracted current directory) and smb_target is the SMB path
++ * where symlink points, therefore full_path must always be on
++ * the SMB share.
++ */
++ int smb_target_len = strlen(smb_target)+1;
++ levels = 0;
++ for (i = 1; full_path[i]; i++) { /* i=1 to skip leading sep */
++ if (full_path[i] == sep)
++ levels++;
++ }
++ linux_target = kmalloc(levels*3 + smb_target_len, GFP_KERNEL);
++ if (!linux_target) {
++ rc = -ENOMEM;
++ goto out;
++ }
++ for (i = 0; i < levels; i++) {
++ linux_target[i*3 + 0] = '.';
++ linux_target[i*3 + 1] = '.';
++ linux_target[i*3 + 2] = sep;
++ }
++ memcpy(linux_target + levels*3, smb_target+1, smb_target_len); /* +1 to skip leading sep */
++ } else {
++ linux_target = smb_target;
++ smb_target = NULL;
++ }
++
++ if (sep == '\\')
++ convert_delimiter(linux_target, '/');
++
++ rc = 0;
++ *target = linux_target;
++
++ cifs_dbg(FYI, "%s: symlink target: %s\n", __func__, *target);
++
++out:
++ if (rc != 0)
++ kfree(linux_target);
++ kfree(smb_target);
++ return rc;
++}
++
+ static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym,
+ u32 plen, bool unicode,
+ struct cifs_sb_info *cifs_sb,
++ const char *full_path,
+ struct cifs_open_info_data *data)
+ {
+ unsigned int len;
+@@ -549,20 +619,18 @@ static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym,
+ return -EIO;
+ }
+
+- data->symlink_target = cifs_strndup_from_utf16(sym->PathBuffer + offs,
+- len, unicode,
+- cifs_sb->local_nls);
+- if (!data->symlink_target)
+- return -ENOMEM;
+-
+- convert_delimiter(data->symlink_target, '/');
+- cifs_dbg(FYI, "%s: target path: %s\n", __func__, data->symlink_target);
+-
+- return 0;
++ return smb2_parse_native_symlink(&data->symlink_target,
++ sym->PathBuffer + offs,
++ len,
++ unicode,
++ le32_to_cpu(sym->Flags) & SYMLINK_FLAG_RELATIVE,
++ full_path,
++ cifs_sb);
+ }
+
+ int parse_reparse_point(struct reparse_data_buffer *buf,
+ u32 plen, struct cifs_sb_info *cifs_sb,
++ const char *full_path,
+ bool unicode, struct cifs_open_info_data *data)
+ {
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+@@ -577,7 +645,7 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
+ case IO_REPARSE_TAG_SYMLINK:
+ return parse_reparse_symlink(
+ (struct reparse_symlink_data_buffer *)buf,
+- plen, unicode, cifs_sb, data);
++ plen, unicode, cifs_sb, full_path, data);
+ case IO_REPARSE_TAG_LX_SYMLINK:
+ case IO_REPARSE_TAG_AF_UNIX:
+ case IO_REPARSE_TAG_LX_FIFO:
+@@ -593,6 +661,7 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
+ }
+
+ int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
++ const char *full_path,
+ struct kvec *rsp_iov,
+ struct cifs_open_info_data *data)
+ {
+@@ -602,7 +671,7 @@ int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
+
+ buf = (struct reparse_data_buffer *)((u8 *)io +
+ le32_to_cpu(io->OutputOffset));
+- return parse_reparse_point(buf, plen, cifs_sb, true, data);
++ return parse_reparse_point(buf, plen, cifs_sb, full_path, true, data);
+ }
+
+ static void wsl_to_fattr(struct cifs_open_info_data *data,
+diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h
+index 158e7b7aae646c..ff05b0e75c9284 100644
+--- a/fs/smb/client/reparse.h
++++ b/fs/smb/client/reparse.h
+@@ -12,6 +12,8 @@
+ #include "fs_context.h"
+ #include "cifsglob.h"
+
++#define REPARSE_SYM_PATH_MAX 4060
++
+ /*
+ * Used only by cifs.ko to ignore reparse points from files when client or
+ * server doesn't support FSCTL_GET_REPARSE_POINT.
+@@ -115,7 +117,9 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
+ int smb2_mknod_reparse(unsigned int xid, struct inode *inode,
+ struct dentry *dentry, struct cifs_tcon *tcon,
+ const char *full_path, umode_t mode, dev_t dev);
+-int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, struct kvec *rsp_iov,
++int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
++ const char *full_path,
++ struct kvec *rsp_iov,
+ struct cifs_open_info_data *data);
+
+ #endif /* _CIFS_REPARSE_H */
+diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
+index e3a195824b4037..b0c0572f9d1fbc 100644
+--- a/fs/smb/client/smb1ops.c
++++ b/fs/smb/client/smb1ops.c
+@@ -994,17 +994,17 @@ static int cifs_query_symlink(const unsigned int xid,
+ }
+
+ static int cifs_parse_reparse_point(struct cifs_sb_info *cifs_sb,
++ const char *full_path,
+ struct kvec *rsp_iov,
+ struct cifs_open_info_data *data)
+ {
+ struct reparse_data_buffer *buf;
+ TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base;
+- bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE);
+ u32 plen = le16_to_cpu(io->ByteCount);
+
+ buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +
+ le32_to_cpu(io->DataOffset));
+- return parse_reparse_point(buf, plen, cifs_sb, unicode, data);
++ return parse_reparse_point(buf, plen, cifs_sb, full_path, true, data);
+ }
+
+ static bool
+diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c
+index e0ee96d69d4952..db9c807115c605 100644
+--- a/fs/smb/client/smb2file.c
++++ b/fs/smb/client/smb2file.c
+@@ -63,12 +63,12 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
+ return sym;
+ }
+
+-int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path)
++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov,
++ const char *full_path, char **path)
+ {
+ struct smb2_symlink_err_rsp *sym;
+ unsigned int sub_offs, sub_len;
+ unsigned int print_offs, print_len;
+- char *s;
+
+ if (!cifs_sb || !iov || !iov->iov_base || !iov->iov_len || !path)
+ return -EINVAL;
+@@ -86,15 +86,13 @@ int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec
+ iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + print_offs + print_len)
+ return -EINVAL;
+
+- s = cifs_strndup_from_utf16((char *)sym->PathBuffer + sub_offs, sub_len, true,
+- cifs_sb->local_nls);
+- if (!s)
+- return -ENOMEM;
+- convert_delimiter(s, '/');
+- cifs_dbg(FYI, "%s: symlink target: %s\n", __func__, s);
+-
+- *path = s;
+- return 0;
++ return smb2_parse_native_symlink(path,
++ (char *)sym->PathBuffer + sub_offs,
++ sub_len,
++ true,
++ le32_to_cpu(sym->Flags) & SYMLINK_FLAG_RELATIVE,
++ full_path,
++ cifs_sb);
+ }
+
+ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf)
+@@ -126,6 +124,7 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
+ goto out;
+ if (hdr->Status == STATUS_STOPPED_ON_SYMLINK) {
+ rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
++ oparms->path,
+ &data->symlink_target);
+ if (!rc) {
+ memset(smb2_data, 0, sizeof(*smb2_data));
+diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
+index daa841dfbadcf4..8ea476b1fe199d 100644
+--- a/fs/smb/client/smb2inode.c
++++ b/fs/smb/client/smb2inode.c
+@@ -828,6 +828,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+
+ static int parse_create_response(struct cifs_open_info_data *data,
+ struct cifs_sb_info *cifs_sb,
++ const char *full_path,
+ const struct kvec *iov)
+ {
+ struct smb2_create_rsp *rsp = iov->iov_base;
+@@ -841,6 +842,7 @@ static int parse_create_response(struct cifs_open_info_data *data,
+ break;
+ case STATUS_STOPPED_ON_SYMLINK:
+ rc = smb2_parse_symlink_response(cifs_sb, iov,
++ full_path,
+ &data->symlink_target);
+ if (rc)
+ return rc;
+@@ -930,14 +932,14 @@ int smb2_query_path_info(const unsigned int xid,
+
+ switch (rc) {
+ case 0:
+- rc = parse_create_response(data, cifs_sb, &out_iov[0]);
++ rc = parse_create_response(data, cifs_sb, full_path, &out_iov[0]);
+ break;
+ case -EOPNOTSUPP:
+ /*
+ * BB TODO: When support for special files added to Samba
+ * re-verify this path.
+ */
+- rc = parse_create_response(data, cifs_sb, &out_iov[0]);
++ rc = parse_create_response(data, cifs_sb, full_path, &out_iov[0]);
+ if (rc || !data->reparse_point)
+ goto out;
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index ab6e79be2c15dd..6645f147d57c29 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -4016,7 +4016,7 @@ map_oplock_to_lease(u8 oplock)
+ if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
+ return SMB2_LEASE_WRITE_CACHING_LE | SMB2_LEASE_READ_CACHING_LE;
+ else if (oplock == SMB2_OPLOCK_LEVEL_II)
+- return SMB2_LEASE_READ_CACHING_LE;
++ return SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE;
+ else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
+ return SMB2_LEASE_HANDLE_CACHING_LE | SMB2_LEASE_READ_CACHING_LE |
+ SMB2_LEASE_WRITE_CACHING_LE;
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index a86a3fbfb5a49c..38b26468eb0c53 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -1228,7 +1228,9 @@ SMB2_negotiate(const unsigned int xid,
+ * SMB3.0 supports only 1 cipher and doesn't have a encryption neg context
+ * Set the cipher type manually.
+ */
+- if (server->dialect == SMB30_PROT_ID && (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
++ if ((server->dialect == SMB30_PROT_ID ||
++ server->dialect == SMB302_PROT_ID) &&
++ (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
+ server->cipher_type = SMB2_ENCRYPTION_AES128_CCM;
+
+ security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
+diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
+index f6fafa997e991d..613667b46c5802 100644
+--- a/fs/smb/client/smb2proto.h
++++ b/fs/smb/client/smb2proto.h
+@@ -113,7 +113,14 @@ extern int smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb,
+ const unsigned char *path, char *pbuf,
+ unsigned int *pbytes_read);
+-int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path);
++int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
++ bool unicode, bool relative,
++ const char *full_path,
++ struct cifs_sb_info *cifs_sb);
++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb,
++ const struct kvec *iov,
++ const char *full_path,
++ char **path);
+ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
+ void *buf);
+ extern int smb2_unlock_range(struct cifsFileInfo *cfile,
+diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
+index 604e52876cd2d9..563cb4d8edf0c3 100644
+--- a/fs/smb/client/trace.h
++++ b/fs/smb/client/trace.h
+@@ -27,6 +27,8 @@
+ EM(netfs_trace_tcon_ref_free_ipc, "FRE Ipc ") \
+ EM(netfs_trace_tcon_ref_free_ipc_fail, "FRE Ipc-F ") \
+ EM(netfs_trace_tcon_ref_free_reconnect_server, "FRE Reconn") \
++ EM(netfs_trace_tcon_ref_get_cached_laundromat, "GET Ch-Lau") \
++ EM(netfs_trace_tcon_ref_get_cached_lease_break, "GET Ch-Lea") \
+ EM(netfs_trace_tcon_ref_get_cancelled_close, "GET Cn-Cls") \
+ EM(netfs_trace_tcon_ref_get_dfs_refer, "GET DfsRef") \
+ EM(netfs_trace_tcon_ref_get_find, "GET Find ") \
+@@ -35,6 +37,7 @@
+ EM(netfs_trace_tcon_ref_new, "NEW ") \
+ EM(netfs_trace_tcon_ref_new_ipc, "NEW Ipc ") \
+ EM(netfs_trace_tcon_ref_new_reconnect_server, "NEW Reconn") \
++ EM(netfs_trace_tcon_ref_put_cached_close, "PUT Ch-Cls") \
+ EM(netfs_trace_tcon_ref_put_cancelled_close, "PUT Cn-Cls") \
+ EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \
+ EM(netfs_trace_tcon_ref_put_cancelled_mid, "PUT Cn-Mid") \
+diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
+index b6e0b71c281dcf..1450e007ac701d 100644
+--- a/fs/smb/server/server.c
++++ b/fs/smb/server/server.c
+@@ -276,8 +276,12 @@ static void handle_ksmbd_work(struct work_struct *wk)
+ * disconnection. waitqueue_active is safe because it
+ * uses atomic operation for condition.
+ */
++ atomic_inc(&conn->refcnt);
+ if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
+ wake_up(&conn->r_count_q);
++
++ if (atomic_dec_and_test(&conn->refcnt))
++ kfree(conn);
+ }
+
+ /**
+diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
+index b08fb28d16b55b..3409488d39ba1c 100644
+--- a/fs/ubifs/super.c
++++ b/fs/ubifs/super.c
+@@ -777,10 +777,10 @@ static void init_constants_master(struct ubifs_info *c)
+ * necessary to report something for the 'statfs()' call.
+ *
+ * Subtract the LEB reserved for GC, the LEB which is reserved for
+- * deletions, minimum LEBs for the index, and assume only one journal
+- * head is available.
++ * deletions, minimum LEBs for the index, the LEBs which are reserved
++ * for each journal head.
+ */
+- tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt + 1;
++ tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt;
+ tmp64 *= (long long)c->leb_size - c->leb_overhead;
+ tmp64 = ubifs_reported_space(c, tmp64);
+ c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT;
+diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
+index a55e04822d16e9..7c43e0ccf6d47d 100644
+--- a/fs/ubifs/tnc_commit.c
++++ b/fs/ubifs/tnc_commit.c
+@@ -657,6 +657,8 @@ static int get_znodes_to_commit(struct ubifs_info *c)
+ znode->alt = 0;
+ cnext = find_next_dirty(znode);
+ if (!cnext) {
++ ubifs_assert(c, !znode->parent);
++ znode->cparent = NULL;
+ znode->cnext = c->cnext;
+ break;
+ }
+diff --git a/fs/unicode/utf8-core.c b/fs/unicode/utf8-core.c
+index 8395066341a437..0400824ef4936e 100644
+--- a/fs/unicode/utf8-core.c
++++ b/fs/unicode/utf8-core.c
+@@ -198,7 +198,7 @@ struct unicode_map *utf8_load(unsigned int version)
+ return um;
+
+ out_symbol_put:
+- symbol_put(um->tables);
++ symbol_put(utf8_data_table);
+ out_free_um:
+ kfree(um);
+ return ERR_PTR(-EINVAL);
+diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
+index 424acdd4b0fca4..50dd27b0f21577 100644
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -260,13 +260,6 @@ xfs_validate_sb_write(
+ * the kernel cannot support since we checked for unsupported bits in
+ * the read verifier, which means that memory is corrupt.
+ */
+- if (xfs_sb_has_compat_feature(sbp, XFS_SB_FEAT_COMPAT_UNKNOWN)) {
+- xfs_warn(mp,
+-"Corruption detected in superblock compatible features (0x%x)!",
+- (sbp->sb_features_compat & XFS_SB_FEAT_COMPAT_UNKNOWN));
+- return -EFSCORRUPTED;
+- }
+-
+ if (!xfs_is_readonly(mp) &&
+ xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
+ xfs_alert(mp,
+diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
+index 9f9d3abad2cf35..d11de0fa5c5f80 100644
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -2456,7 +2456,10 @@ xlog_recover_process_data(
+
+ ohead = (struct xlog_op_header *)dp;
+ dp += sizeof(*ohead);
+- ASSERT(dp <= end);
++ if (dp > end) {
++ xfs_warn(log->l_mp, "%s: op header overrun", __func__);
++ return -EFSCORRUPTED;
++ }
+
+ /* errors will abort recovery */
+ error = xlog_recover_process_ophdr(log, rhash, rhead, ohead,
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index 63029bc7c9dd01..7e11ca6f86dcda 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -139,14 +139,6 @@
+ * often happens at runtime)
+ */
+
+-#if defined(CONFIG_MEMORY_HOTPLUG)
+-#define MEM_KEEP(sec) *(.mem##sec)
+-#define MEM_DISCARD(sec)
+-#else
+-#define MEM_KEEP(sec)
+-#define MEM_DISCARD(sec) *(.mem##sec)
+-#endif
+-
+ #ifndef CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE
+ #define KEEP_PATCHABLE KEEP(*(__patchable_function_entries))
+ #define PATCHABLE_DISCARDS
+@@ -355,10 +347,9 @@
+ *(.data..decrypted) \
+ *(.ref.data) \
+ *(.data..shared_aligned) /* percpu related */ \
+- MEM_KEEP(init.data*) \
+- *(.data.unlikely) \
++ *(.data..unlikely) \
+ __start_once = .; \
+- *(.data.once) \
++ *(.data..once) \
+ __end_once = .; \
+ STRUCT_ALIGN(); \
+ *(__tracepoints) \
+@@ -519,7 +510,6 @@
+ /* __*init sections */ \
+ __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \
+ *(.ref.rodata) \
+- MEM_KEEP(init.rodata) \
+ } \
+ \
+ /* Built-in module parameters. */ \
+@@ -570,8 +560,7 @@
+ *(.text.unknown .text.unknown.*) \
+ NOINSTR_TEXT \
+ *(.ref.text) \
+- *(.text.asan.* .text.tsan.*) \
+- MEM_KEEP(init.text*) \
++ *(.text.asan.* .text.tsan.*)
+
+
+ /* sched.text is aling to function alignment to secure we have same
+@@ -678,7 +667,6 @@
+ #define INIT_DATA \
+ KEEP(*(SORT(___kentry+*))) \
+ *(.init.data .init.data.*) \
+- MEM_DISCARD(init.data*) \
+ KERNEL_CTORS() \
+ MCOUNT_REC() \
+ *(.init.rodata .init.rodata.*) \
+@@ -686,7 +674,6 @@
+ TRACE_SYSCALLS() \
+ KPROBE_BLACKLIST() \
+ ERROR_INJECT_WHITELIST() \
+- MEM_DISCARD(init.rodata) \
+ CLK_OF_TABLES() \
+ RESERVEDMEM_OF_TABLES() \
+ TIMER_OF_TABLES() \
+@@ -704,8 +691,7 @@
+
+ #define INIT_TEXT \
+ *(.init.text .init.text.*) \
+- *(.text.startup) \
+- MEM_DISCARD(init.text*)
++ *(.text.startup)
+
+ #define EXIT_DATA \
+ *(.exit.data .exit.data.*) \
+diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h
+index 6e950594215a0f..99ae7960a8d13c 100644
+--- a/include/linux/avf/virtchnl.h
++++ b/include/linux/avf/virtchnl.h
+@@ -245,6 +245,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
+ #define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES BIT(6)
+ /* used to negotiate communicating link speeds in Mbps */
+ #define VIRTCHNL_VF_CAP_ADV_LINK_SPEED BIT(7)
++#define VIRTCHNL_VF_OFFLOAD_CRC BIT(10)
+ #define VIRTCHNL_VF_OFFLOAD_VLAN_V2 BIT(15)
+ #define VIRTCHNL_VF_OFFLOAD_VLAN BIT(16)
+ #define VIRTCHNL_VF_OFFLOAD_RX_POLLING BIT(17)
+@@ -300,7 +301,13 @@ VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info);
+ /* VIRTCHNL_OP_CONFIG_RX_QUEUE
+ * VF sends this message to set up parameters for one RX queue.
+ * External data buffer contains one instance of virtchnl_rxq_info.
+- * PF configures requested queue and returns a status code.
++ * PF configures requested queue and returns a status code. The
++ * crc_disable flag disables CRC stripping on the VF. Setting
++ * the crc_disable flag to 1 will disable CRC stripping for each
++ * queue in the VF where the flag is set. The VIRTCHNL_VF_OFFLOAD_CRC
++ * offload must have been set prior to sending this info or the PF
++ * will ignore the request. This flag should be set the same for
++ * all of the queues for a VF.
+ */
+
+ /* Rx queue config info */
+@@ -312,7 +319,7 @@ struct virtchnl_rxq_info {
+ u16 splithdr_enabled; /* deprecated with AVF 1.0 */
+ u32 databuffer_size;
+ u32 max_pkt_size;
+- u8 pad0;
++ u8 crc_disable;
+ u8 rxdid;
+ u8 pad1[2];
+ u64 dma_ring_addr;
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index a7b65d4ab616e2..ef35e9a9878c6a 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -1184,7 +1184,7 @@ static inline unsigned int queue_io_min(const struct request_queue *q)
+ return q->limits.io_min;
+ }
+
+-static inline int bdev_io_min(struct block_device *bdev)
++static inline unsigned int bdev_io_min(struct block_device *bdev)
+ {
+ return queue_io_min(bdev_get_queue(bdev));
+ }
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 92919d52f7e1b2..cb8e97665eaa59 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -319,12 +319,34 @@ struct bpf_func_state {
+ struct bpf_stack_state *stack;
+ };
+
+-struct bpf_idx_pair {
+- u32 prev_idx;
++#define MAX_CALL_FRAMES 8
++
++/* instruction history flags, used in bpf_jmp_history_entry.flags field */
++enum {
++ /* instruction references stack slot through PTR_TO_STACK register;
++ * we also store stack's frame number in lower 3 bits (MAX_CALL_FRAMES is 8)
++ * and accessed stack slot's index in next 6 bits (MAX_BPF_STACK is 512,
++ * 8 bytes per slot, so slot index (spi) is [0, 63])
++ */
++ INSN_F_FRAMENO_MASK = 0x7, /* 3 bits */
++
++ INSN_F_SPI_MASK = 0x3f, /* 6 bits */
++ INSN_F_SPI_SHIFT = 3, /* shifted 3 bits to the left */
++
++ INSN_F_STACK_ACCESS = BIT(9), /* we need 10 bits total */
++};
++
++static_assert(INSN_F_FRAMENO_MASK + 1 >= MAX_CALL_FRAMES);
++static_assert(INSN_F_SPI_MASK + 1 >= MAX_BPF_STACK / 8);
++
++struct bpf_jmp_history_entry {
+ u32 idx;
++ /* insn idx can't be bigger than 1 million */
++ u32 prev_idx : 22;
++ /* special flags, e.g., whether insn is doing register stack spill/load */
++ u32 flags : 10;
+ };
+
+-#define MAX_CALL_FRAMES 8
+ /* Maximum number of register states that can exist at once */
+ #define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) * MAX_CALL_FRAMES)
+ struct bpf_verifier_state {
+@@ -407,7 +429,7 @@ struct bpf_verifier_state {
+ * For most states jmp_history_cnt is [0-3].
+ * For loops can go up to ~40.
+ */
+- struct bpf_idx_pair *jmp_history;
++ struct bpf_jmp_history_entry *jmp_history;
+ u32 jmp_history_cnt;
+ u32 dfs_depth;
+ u32 callback_unroll_depth;
+@@ -640,6 +662,7 @@ struct bpf_verifier_env {
+ int cur_stack;
+ } cfg;
+ struct backtrack_state bt;
++ struct bpf_jmp_history_entry *cur_hist_ent;
+ u32 pass_cnt; /* number of times do_check() was called */
+ u32 subprog_cnt;
+ /* number of instructions analyzed by the verifier */
+diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h
+index f5859b8c68b420..7e0a2efd90ca28 100644
+--- a/include/linux/compiler_attributes.h
++++ b/include/linux/compiler_attributes.h
+@@ -94,19 +94,6 @@
+ # define __copy(symbol)
+ #endif
+
+-/*
+- * Optional: only supported since gcc >= 14
+- * Optional: only supported since clang >= 18
+- *
+- * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
+- * clang: https://reviews.llvm.org/D148381
+- */
+-#if __has_attribute(__counted_by__)
+-# define __counted_by(member) __attribute__((__counted_by__(member)))
+-#else
+-# define __counted_by(member)
+-#endif
+-
+ /*
+ * Optional: not supported by gcc
+ * Optional: only supported since clang >= 14.0
+diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
+index 0a182f088c897e..02f616dfb15f4d 100644
+--- a/include/linux/compiler_types.h
++++ b/include/linux/compiler_types.h
+@@ -295,6 +295,25 @@ struct ftrace_likely_data {
+ #define __no_sanitize_or_inline __always_inline
+ #endif
+
++/*
++ * Optional: only supported since gcc >= 15
++ * Optional: only supported since clang >= 18
++ *
++ * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
++ * clang: https://github.com/llvm/llvm-project/pull/76348
++ *
++ * __bdos on clang < 19.1.2 can erroneously return 0:
++ * https://github.com/llvm/llvm-project/pull/110497
++ *
++ * __bdos on clang < 19.1.3 can be off by 4:
++ * https://github.com/llvm/llvm-project/pull/112636
++ */
++#ifdef CONFIG_CC_HAS_COUNTED_BY
++# define __counted_by(member) __attribute__((__counted_by__(member)))
++#else
++# define __counted_by(member)
++#endif
++
+ /* Section for code which can't be instrumented at all */
+ #define __noinstr_section(section) \
+ noinline notrace __attribute((__section__(section))) \
+diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h
+index 5c4b3a68053f51..8070bff54bfa29 100644
+--- a/include/linux/hisi_acc_qm.h
++++ b/include/linux/hisi_acc_qm.h
+@@ -225,6 +225,12 @@ struct hisi_qm_status {
+
+ struct hisi_qm;
+
++enum acc_err_result {
++ ACC_ERR_NONE,
++ ACC_ERR_NEED_RESET,
++ ACC_ERR_RECOVERED,
++};
++
+ struct hisi_qm_err_info {
+ char *acpi_rst;
+ u32 msi_wr_port;
+@@ -253,9 +259,9 @@ struct hisi_qm_err_ini {
+ void (*close_axi_master_ooo)(struct hisi_qm *qm);
+ void (*open_sva_prefetch)(struct hisi_qm *qm);
+ void (*close_sva_prefetch)(struct hisi_qm *qm);
+- void (*log_dev_hw_err)(struct hisi_qm *qm, u32 err_sts);
+ void (*show_last_dfx_regs)(struct hisi_qm *qm);
+ void (*err_info_init)(struct hisi_qm *qm);
++ enum acc_err_result (*get_err_result)(struct hisi_qm *qm);
+ };
+
+ struct hisi_qm_cap_info {
+diff --git a/include/linux/init.h b/include/linux/init.h
+index 01b52c9c75268f..63d2ee4f1f0e07 100644
+--- a/include/linux/init.h
++++ b/include/linux/init.h
+@@ -84,11 +84,15 @@
+
+ #define __exit __section(".exit.text") __exitused __cold notrace
+
+-/* Used for MEMORY_HOTPLUG */
+-#define __meminit __section(".meminit.text") __cold notrace \
+- __latent_entropy
+-#define __meminitdata __section(".meminit.data")
+-#define __meminitconst __section(".meminit.rodata")
++#ifdef CONFIG_MEMORY_HOTPLUG
++#define __meminit
++#define __meminitdata
++#define __meminitconst
++#else
++#define __meminit __init
++#define __meminitdata __initdata
++#define __meminitconst __initconst
++#endif
+
+ /* For assembly routines */
+ #define __HEAD .section ".head.text","ax"
+diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
+index e0ae2a43e0ebdd..03f38fe9b9a103 100644
+--- a/include/linux/jiffies.h
++++ b/include/linux/jiffies.h
+@@ -499,7 +499,7 @@ static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+ * - all other values are converted to jiffies by either multiplying
+ * the input value by a factor or dividing it with a factor and
+ * handling any 32-bit overflows.
+- * for the details see __msecs_to_jiffies()
++ * for the details see _msecs_to_jiffies()
+ *
+ * msecs_to_jiffies() checks for the passed in value being a constant
+ * via __builtin_constant_p() allowing gcc to eliminate most of the
+diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
+index dc2844b071c2c2..919a5cb6368d17 100644
+--- a/include/linux/lockdep.h
++++ b/include/linux/lockdep.h
+@@ -230,7 +230,7 @@ static inline void lockdep_init_map(struct lockdep_map *lock, const char *name,
+ (lock)->dep_map.lock_type)
+
+ #define lockdep_set_subclass(lock, sub) \
+- lockdep_init_map_type(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\
++ lockdep_init_map_type(&(lock)->dep_map, (lock)->dep_map.name, (lock)->dep_map.key, sub,\
+ (lock)->dep_map.wait_type_inner, \
+ (lock)->dep_map.wait_type_outer, \
+ (lock)->dep_map.lock_type)
+diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h
+index 7c3e7b0b0e8fd6..28c21d5b25f6b7 100644
+--- a/include/linux/mmdebug.h
++++ b/include/linux/mmdebug.h
+@@ -46,7 +46,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);
+ } \
+ } while (0)
+ #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \
+- static bool __section(".data.once") __warned; \
++ static bool __section(".data..once") __warned; \
+ int __ret_warn_once = !!(cond); \
+ \
+ if (unlikely(__ret_warn_once && !__warned)) { \
+@@ -66,7 +66,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);
+ unlikely(__ret_warn); \
+ })
+ #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \
+- static bool __section(".data.once") __warned; \
++ static bool __section(".data..once") __warned; \
+ int __ret_warn_once = !!(cond); \
+ \
+ if (unlikely(__ret_warn_once && !__warned)) { \
+@@ -77,7 +77,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);
+ unlikely(__ret_warn_once); \
+ })
+ #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \
+- static bool __section(".data.once") __warned; \
++ static bool __section(".data..once") __warned; \
+ int __ret_warn_once = !!(cond); \
+ \
+ if (unlikely(__ret_warn_once && !__warned)) { \
+diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
+index bd19c4b91e3120..3ddf205b7e2c38 100644
+--- a/include/linux/netpoll.h
++++ b/include/linux/netpoll.h
+@@ -71,7 +71,7 @@ static inline void *netpoll_poll_lock(struct napi_struct *napi)
+ {
+ struct net_device *dev = napi->dev;
+
+- if (dev && dev->npinfo) {
++ if (dev && rcu_access_pointer(dev->npinfo)) {
+ int owner = smp_processor_id();
+
+ while (cmpxchg(&napi->poll_owner, -1, owner) != -1)
+diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
+index d69ad5bb1eb1e6..b8d6c0c208760a 100644
+--- a/include/linux/of_fdt.h
++++ b/include/linux/of_fdt.h
+@@ -31,6 +31,7 @@ extern void *of_fdt_unflatten_tree(const unsigned long *blob,
+ extern int __initdata dt_root_addr_cells;
+ extern int __initdata dt_root_size_cells;
+ extern void *initial_boot_params;
++extern phys_addr_t initial_boot_params_pa;
+
+ extern char __dtb_start[];
+ extern char __dtb_end[];
+@@ -70,8 +71,8 @@ extern u64 dt_mem_next_cell(int s, const __be32 **cellp);
+ /* Early flat tree scan hooks */
+ extern int early_init_dt_scan_root(void);
+
+-extern bool early_init_dt_scan(void *params);
+-extern bool early_init_dt_verify(void *params);
++extern bool early_init_dt_scan(void *dt_virt, phys_addr_t dt_phys);
++extern bool early_init_dt_verify(void *dt_virt, phys_addr_t dt_phys);
+ extern void early_init_dt_scan_nodes(void);
+
+ extern const char *of_flat_dt_get_machine_name(void);
+diff --git a/include/linux/once.h b/include/linux/once.h
+index bc714d414448a7..30346fcdc7995d 100644
+--- a/include/linux/once.h
++++ b/include/linux/once.h
+@@ -46,7 +46,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
+ #define DO_ONCE(func, ...) \
+ ({ \
+ bool ___ret = false; \
+- static bool __section(".data.once") ___done = false; \
++ static bool __section(".data..once") ___done = false; \
+ static DEFINE_STATIC_KEY_TRUE(___once_key); \
+ if (static_branch_unlikely(&___once_key)) { \
+ unsigned long ___flags; \
+@@ -64,7 +64,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
+ #define DO_ONCE_SLEEPABLE(func, ...) \
+ ({ \
+ bool ___ret = false; \
+- static bool __section(".data.once") ___done = false; \
++ static bool __section(".data..once") ___done = false; \
+ static DEFINE_STATIC_KEY_TRUE(___once_key); \
+ if (static_branch_unlikely(&___once_key)) { \
+ ___ret = __do_once_sleepable_start(&___done); \
+diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h
+index b7bce4983638f8..27de7bc32a0610 100644
+--- a/include/linux/once_lite.h
++++ b/include/linux/once_lite.h
+@@ -12,7 +12,7 @@
+
+ #define __ONCE_LITE_IF(condition) \
+ ({ \
+- static bool __section(".data.once") __already_done; \
++ static bool __section(".data..once") __already_done; \
+ bool __ret_cond = !!(condition); \
+ bool __ret_once = false; \
+ \
+diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
+index 6466c2f792923c..7602d1f8a9ecb3 100644
+--- a/include/linux/rcupdate.h
++++ b/include/linux/rcupdate.h
+@@ -398,7 +398,7 @@ static inline int debug_lockdep_rcu_enabled(void)
+ */
+ #define RCU_LOCKDEP_WARN(c, s) \
+ do { \
+- static bool __section(".data.unlikely") __warned; \
++ static bool __section(".data..unlikely") __warned; \
+ if (debug_lockdep_rcu_enabled() && (c) && \
+ debug_lockdep_rcu_enabled() && !__warned) { \
+ __warned = true; \
+diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
+index e9bd2f65d7f4e4..b4b4ce9a4151ec 100644
+--- a/include/linux/seqlock.h
++++ b/include/linux/seqlock.h
+@@ -682,6 +682,23 @@ static __always_inline unsigned raw_read_seqcount_latch(const seqcount_latch_t *
+ return READ_ONCE(s->seqcount.sequence);
+ }
+
++/**
++ * read_seqcount_latch() - pick even/odd latch data copy
++ * @s: Pointer to seqcount_latch_t
++ *
++ * See write_seqcount_latch() for details and a full reader/writer usage
++ * example.
++ *
++ * Return: sequence counter raw value. Use the lowest bit as an index for
++ * picking which data copy to read. The full counter must then be checked
++ * with read_seqcount_latch_retry().
++ */
++static __always_inline unsigned read_seqcount_latch(const seqcount_latch_t *s)
++{
++ kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);
++ return raw_read_seqcount_latch(s);
++}
++
+ /**
+ * raw_read_seqcount_latch_retry() - end a seqcount_latch_t read section
+ * @s: Pointer to seqcount_latch_t
+@@ -696,9 +713,34 @@ raw_read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start)
+ return unlikely(READ_ONCE(s->seqcount.sequence) != start);
+ }
+
++/**
++ * read_seqcount_latch_retry() - end a seqcount_latch_t read section
++ * @s: Pointer to seqcount_latch_t
++ * @start: count, from read_seqcount_latch()
++ *
++ * Return: true if a read section retry is required, else false
++ */
++static __always_inline int
++read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start)
++{
++ kcsan_atomic_next(0);
++ return raw_read_seqcount_latch_retry(s, start);
++}
++
+ /**
+ * raw_write_seqcount_latch() - redirect latch readers to even/odd copy
+ * @s: Pointer to seqcount_latch_t
++ */
++static __always_inline void raw_write_seqcount_latch(seqcount_latch_t *s)
++{
++ smp_wmb(); /* prior stores before incrementing "sequence" */
++ s->seqcount.sequence++;
++ smp_wmb(); /* increment "sequence" before following stores */
++}
++
++/**
++ * write_seqcount_latch_begin() - redirect latch readers to odd copy
++ * @s: Pointer to seqcount_latch_t
+ *
+ * The latch technique is a multiversion concurrency control method that allows
+ * queries during non-atomic modifications. If you can guarantee queries never
+@@ -726,17 +768,11 @@ raw_read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start)
+ *
+ * void latch_modify(struct latch_struct *latch, ...)
+ * {
+- * smp_wmb(); // Ensure that the last data[1] update is visible
+- * latch->seq.sequence++;
+- * smp_wmb(); // Ensure that the seqcount update is visible
+- *
++ * write_seqcount_latch_begin(&latch->seq);
+ * modify(latch->data[0], ...);
+- *
+- * smp_wmb(); // Ensure that the data[0] update is visible
+- * latch->seq.sequence++;
+- * smp_wmb(); // Ensure that the seqcount update is visible
+- *
++ * write_seqcount_latch(&latch->seq);
+ * modify(latch->data[1], ...);
++ * write_seqcount_latch_end(&latch->seq);
+ * }
+ *
+ * The query will have a form like::
+@@ -747,13 +783,13 @@ raw_read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start)
+ * unsigned seq, idx;
+ *
+ * do {
+- * seq = raw_read_seqcount_latch(&latch->seq);
++ * seq = read_seqcount_latch(&latch->seq);
+ *
+ * idx = seq & 0x01;
+ * entry = data_query(latch->data[idx], ...);
+ *
+ * // This includes needed smp_rmb()
+- * } while (raw_read_seqcount_latch_retry(&latch->seq, seq));
++ * } while (read_seqcount_latch_retry(&latch->seq, seq));
+ *
+ * return entry;
+ * }
+@@ -777,11 +813,31 @@ raw_read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start)
+ * When data is a dynamic data structure; one should use regular RCU
+ * patterns to manage the lifetimes of the objects within.
+ */
+-static inline void raw_write_seqcount_latch(seqcount_latch_t *s)
++static __always_inline void write_seqcount_latch_begin(seqcount_latch_t *s)
+ {
+- smp_wmb(); /* prior stores before incrementing "sequence" */
+- s->seqcount.sequence++;
+- smp_wmb(); /* increment "sequence" before following stores */
++ kcsan_nestable_atomic_begin();
++ raw_write_seqcount_latch(s);
++}
++
++/**
++ * write_seqcount_latch() - redirect latch readers to even copy
++ * @s: Pointer to seqcount_latch_t
++ */
++static __always_inline void write_seqcount_latch(seqcount_latch_t *s)
++{
++ raw_write_seqcount_latch(s);
++}
++
++/**
++ * write_seqcount_latch_end() - end a seqcount_latch_t write section
++ * @s: Pointer to seqcount_latch_t
++ *
++ * Marks the end of a seqcount_latch_t writer section, after all copies of the
++ * latch-protected data have been updated.
++ */
++static __always_inline void write_seqcount_latch_end(seqcount_latch_t *s)
++{
++ kcsan_nestable_atomic_end();
+ }
+
+ /*
+@@ -834,11 +890,7 @@ typedef struct {
+ */
+ static inline unsigned read_seqbegin(const seqlock_t *sl)
+ {
+- unsigned ret = read_seqcount_begin(&sl->seqcount);
+-
+- kcsan_atomic_next(0); /* non-raw usage, assume closing read_seqretry() */
+- kcsan_flat_atomic_begin();
+- return ret;
++ return read_seqcount_begin(&sl->seqcount);
+ }
+
+ /**
+@@ -854,12 +906,6 @@ static inline unsigned read_seqbegin(const seqlock_t *sl)
+ */
+ static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start)
+ {
+- /*
+- * Assume not nested: read_seqretry() may be called multiple times when
+- * completing read critical section.
+- */
+- kcsan_flat_atomic_end();
+-
+ return read_seqcount_retry(&sl->seqcount, start);
+ }
+
+diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
+index 0b9ecd8cf9793b..110978dc9af1b1 100644
+--- a/include/linux/sock_diag.h
++++ b/include/linux/sock_diag.h
+@@ -13,6 +13,7 @@ struct nlmsghdr;
+ struct sock;
+
+ struct sock_diag_handler {
++ struct module *owner;
+ __u8 family;
+ int (*dump)(struct sk_buff *skb, struct nlmsghdr *nlh);
+ int (*get_info)(struct sk_buff *skb, struct sock *sk);
+@@ -22,8 +23,13 @@ struct sock_diag_handler {
+ int sock_diag_register(const struct sock_diag_handler *h);
+ void sock_diag_unregister(const struct sock_diag_handler *h);
+
+-void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
+-void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
++struct sock_diag_inet_compat {
++ struct module *owner;
++ int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh);
++};
++
++void sock_diag_register_inet_compat(const struct sock_diag_inet_compat *ptr);
++void sock_diag_unregister_inet_compat(const struct sock_diag_inet_compat *ptr);
+
+ u64 __sock_gen_cookie(struct sock *sk);
+
+diff --git a/include/linux/util_macros.h b/include/linux/util_macros.h
+index 6bb460c3e818b3..825487fb66faf9 100644
+--- a/include/linux/util_macros.h
++++ b/include/linux/util_macros.h
+@@ -4,19 +4,6 @@
+
+ #include <linux/math.h>
+
+-#define __find_closest(x, a, as, op) \
+-({ \
+- typeof(as) __fc_i, __fc_as = (as) - 1; \
+- typeof(x) __fc_x = (x); \
+- typeof(*a) const *__fc_a = (a); \
+- for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \
+- if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \
+- __fc_a[__fc_i + 1], 2)) \
+- break; \
+- } \
+- (__fc_i); \
+-})
+-
+ /**
+ * find_closest - locate the closest element in a sorted array
+ * @x: The reference value.
+@@ -25,8 +12,27 @@
+ * @as: Size of 'a'.
+ *
+ * Returns the index of the element closest to 'x'.
++ * Note: If using an array of negative numbers (or mixed positive numbers),
++ * then be sure that 'x' is of a signed-type to get good results.
+ */
+-#define find_closest(x, a, as) __find_closest(x, a, as, <=)
++#define find_closest(x, a, as) \
++({ \
++ typeof(as) __fc_i, __fc_as = (as) - 1; \
++ long __fc_mid_x, __fc_x = (x); \
++ long __fc_left, __fc_right; \
++ typeof(*a) const *__fc_a = (a); \
++ for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \
++ __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i + 1]) / 2; \
++ if (__fc_x <= __fc_mid_x) { \
++ __fc_left = __fc_x - __fc_a[__fc_i]; \
++ __fc_right = __fc_a[__fc_i + 1] - __fc_x; \
++ if (__fc_right < __fc_left) \
++ __fc_i++; \
++ break; \
++ } \
++ } \
++ (__fc_i); \
++})
+
+ /**
+ * find_closest_descending - locate the closest element in a sorted array
+@@ -36,9 +42,27 @@
+ * @as: Size of 'a'.
+ *
+ * Similar to find_closest() but 'a' is expected to be sorted in descending
+- * order.
++ * order. The iteration is done in reverse order, so that the comparison
++ * of '__fc_right' & '__fc_left' also works for unsigned numbers.
+ */
+-#define find_closest_descending(x, a, as) __find_closest(x, a, as, >=)
++#define find_closest_descending(x, a, as) \
++({ \
++ typeof(as) __fc_i, __fc_as = (as) - 1; \
++ long __fc_mid_x, __fc_x = (x); \
++ long __fc_left, __fc_right; \
++ typeof(*a) const *__fc_a = (a); \
++ for (__fc_i = __fc_as; __fc_i >= 1; __fc_i--) { \
++ __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i - 1]) / 2; \
++ if (__fc_x <= __fc_mid_x) { \
++ __fc_left = __fc_x - __fc_a[__fc_i]; \
++ __fc_right = __fc_a[__fc_i - 1] - __fc_x; \
++ if (__fc_right < __fc_left) \
++ __fc_i--; \
++ break; \
++ } \
++ } \
++ (__fc_i); \
++})
+
+ /**
+ * is_insidevar - check if the @ptr points inside the @var memory range.
+diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
+index 8fa963326bf6a2..c64096b5c78215 100644
+--- a/include/media/v4l2-dv-timings.h
++++ b/include/media/v4l2-dv-timings.h
+@@ -146,15 +146,18 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
+ * @polarities: the horizontal and vertical polarities (same as struct
+ * v4l2_bt_timings polarities).
+ * @interlaced: if this flag is true, it indicates interlaced format
++ * @cap: the v4l2_dv_timings_cap capabilities.
+ * @fmt: the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid CVT format. If so, then it will return true, and fmt will be filled
+ * in with the found CVT timings.
+ */
+-bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
+- unsigned active_width, u32 polarities, bool interlaced,
+- struct v4l2_dv_timings *fmt);
++bool v4l2_detect_cvt(unsigned int frame_height, unsigned int hfreq,
++ unsigned int vsync, unsigned int active_width,
++ u32 polarities, bool interlaced,
++ const struct v4l2_dv_timings_cap *cap,
++ struct v4l2_dv_timings *fmt);
+
+ /**
+ * v4l2_detect_gtf - detect if the given timings follow the GTF standard
+@@ -170,15 +173,18 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
+ * image height, so it has to be passed explicitly. Usually
+ * the native screen aspect ratio is used for this. If it
+ * is not filled in correctly, then 16:9 will be assumed.
++ * @cap: the v4l2_dv_timings_cap capabilities.
+ * @fmt: the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid GTF format. If so, then it will return true, and fmt will be filled
+ * in with the found GTF timings.
+ */
+-bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync,
+- u32 polarities, bool interlaced, struct v4l2_fract aspect,
+- struct v4l2_dv_timings *fmt);
++bool v4l2_detect_gtf(unsigned int frame_height, unsigned int hfreq,
++ unsigned int vsync, u32 polarities, bool interlaced,
++ struct v4l2_fract aspect,
++ const struct v4l2_dv_timings_cap *cap,
++ struct v4l2_dv_timings *fmt);
+
+ /**
+ * v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes
+diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
+index 2338f8d2a8b33b..c6cb6f64274232 100644
+--- a/include/net/ieee80211_radiotap.h
++++ b/include/net/ieee80211_radiotap.h
+@@ -24,25 +24,27 @@
+ * struct ieee80211_radiotap_header - base radiotap header
+ */
+ struct ieee80211_radiotap_header {
+- /**
+- * @it_version: radiotap version, always 0
+- */
+- uint8_t it_version;
+-
+- /**
+- * @it_pad: padding (or alignment)
+- */
+- uint8_t it_pad;
+-
+- /**
+- * @it_len: overall radiotap header length
+- */
+- __le16 it_len;
+-
+- /**
+- * @it_present: (first) present word
+- */
+- __le32 it_present;
++ __struct_group(ieee80211_radiotap_header_fixed, hdr, __packed,
++ /**
++ * @it_version: radiotap version, always 0
++ */
++ uint8_t it_version;
++
++ /**
++ * @it_pad: padding (or alignment)
++ */
++ uint8_t it_pad;
++
++ /**
++ * @it_len: overall radiotap header length
++ */
++ __le16 it_len;
++
++ /**
++ * @it_present: (first) present word
++ */
++ __le32 it_present;
++ );
+
+ /**
+ * @it_optional: all remaining presence bitmaps
+@@ -50,6 +52,9 @@ struct ieee80211_radiotap_header {
+ __le32 it_optional[];
+ } __packed;
+
++static_assert(offsetof(struct ieee80211_radiotap_header, it_optional) == sizeof(struct ieee80211_radiotap_header_fixed),
++ "struct member likely outside of __struct_group()");
++
+ /* version is always 0 */
+ #define PKTHDR_RADIOTAP_VERSION 0
+
+diff --git a/include/net/net_debug.h b/include/net/net_debug.h
+index 1e74684cbbdbcd..4a79204c8d306e 100644
+--- a/include/net/net_debug.h
++++ b/include/net/net_debug.h
+@@ -27,7 +27,7 @@ void netdev_info(const struct net_device *dev, const char *format, ...);
+
+ #define netdev_level_once(level, dev, fmt, ...) \
+ do { \
+- static bool __section(".data.once") __print_once; \
++ static bool __section(".data..once") __print_once; \
+ \
+ if (!__print_once) { \
+ __print_once = true; \
+diff --git a/include/net/sock.h b/include/net/sock.h
+index e0be8bd9839602..a6b795ec7c9cb6 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2219,7 +2219,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst)
+
+ sk_tx_queue_clear(sk);
+ WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
+- old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst);
++ old_dst = unrcu_pointer(xchg(&sk->sk_dst_cache, RCU_INITIALIZER(dst)));
+ dst_release(old_dst);
+ }
+
+diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
+index 51c13cf9c5aee4..63a0922937e72c 100644
+--- a/include/uapi/linux/rtnetlink.h
++++ b/include/uapi/linux/rtnetlink.h
+@@ -174,7 +174,7 @@ enum {
+ #define RTM_GETLINKPROP RTM_GETLINKPROP
+
+ RTM_NEWVLAN = 112,
+-#define RTM_NEWNVLAN RTM_NEWVLAN
++#define RTM_NEWVLAN RTM_NEWVLAN
+ RTM_DELVLAN,
+ #define RTM_DELVLAN RTM_DELVLAN
+ RTM_GETVLAN,
+diff --git a/init/Kconfig b/init/Kconfig
+index 6054ba684c5396..60ed7713b5ee2a 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -107,6 +107,15 @@ config CC_HAS_ASM_INLINE
+ config CC_HAS_NO_PROFILE_FN_ATTR
+ def_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror)
+
++config CC_HAS_COUNTED_BY
++ # TODO: when gcc 15 is released remove the build test and add
++ # a gcc version check
++ def_bool $(success,echo 'struct flex { int count; int array[] __attribute__((__counted_by__(count))); };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
++ # clang needs to be at least 19.1.3 to avoid __bdos miscalculations
++ # https://github.com/llvm/llvm-project/pull/110497
++ # https://github.com/llvm/llvm-project/pull/112636
++ depends on !(CC_IS_CLANG && CLANG_VERSION < 190103)
++
+ config PAHOLE_VERSION
+ int
+ default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
+diff --git a/init/initramfs.c b/init/initramfs.c
+index efc477b905a482..148988bd8ab277 100644
+--- a/init/initramfs.c
++++ b/init/initramfs.c
+@@ -358,6 +358,15 @@ static int __init do_name(void)
+ {
+ state = SkipIt;
+ next_state = Reset;
++
++ /* name_len > 0 && name_len <= PATH_MAX checked in do_header */
++ if (collected[name_len - 1] != '\0') {
++ pr_err("initramfs name without nulterm: %.*s\n",
++ (int)name_len, collected);
++ error("malformed archive");
++ return 1;
++ }
++
+ if (strcmp(collected, "TRAILER!!!") == 0) {
+ free_hash();
+ return 0;
+@@ -422,6 +431,12 @@ static int __init do_copy(void)
+
+ static int __init do_symlink(void)
+ {
++ if (collected[name_len - 1] != '\0') {
++ pr_err("initramfs symlink without nulterm: %.*s\n",
++ (int)name_len, collected);
++ error("malformed archive");
++ return 1;
++ }
+ collected[N_ALIGN(name_len) + body_len] = '\0';
+ clean_path(collected, 0);
+ init_symlink(collected + N_ALIGN(name_len), collected);
+diff --git a/ipc/namespace.c b/ipc/namespace.c
+index 6ecc30effd3ec6..4df91ceeeafe9f 100644
+--- a/ipc/namespace.c
++++ b/ipc/namespace.c
+@@ -83,13 +83,15 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
+
+ err = msg_init_ns(ns);
+ if (err)
+- goto fail_put;
++ goto fail_ipc;
+
+ sem_init_ns(ns);
+ shm_init_ns(ns);
+
+ return ns;
+
++fail_ipc:
++ retire_ipc_sysctls(ns);
+ fail_mq:
+ retire_mq_sysctls(ns);
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 4f19a091571bb6..5ca02af3a87280 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1762,8 +1762,8 @@ static int copy_verifier_state(struct bpf_verifier_state *dst_state,
+ int i, err;
+
+ dst_state->jmp_history = copy_array(dst_state->jmp_history, src->jmp_history,
+- src->jmp_history_cnt, sizeof(struct bpf_idx_pair),
+- GFP_USER);
++ src->jmp_history_cnt, sizeof(*dst_state->jmp_history),
++ GFP_USER);
+ if (!dst_state->jmp_history)
+ return -ENOMEM;
+ dst_state->jmp_history_cnt = src->jmp_history_cnt;
+@@ -3397,6 +3397,21 @@ static int check_reg_arg(struct bpf_verifier_env *env, u32 regno,
+ return __check_reg_arg(env, state->regs, regno, t);
+ }
+
++static int insn_stack_access_flags(int frameno, int spi)
++{
++ return INSN_F_STACK_ACCESS | (spi << INSN_F_SPI_SHIFT) | frameno;
++}
++
++static int insn_stack_access_spi(int insn_flags)
++{
++ return (insn_flags >> INSN_F_SPI_SHIFT) & INSN_F_SPI_MASK;
++}
++
++static int insn_stack_access_frameno(int insn_flags)
++{
++ return insn_flags & INSN_F_FRAMENO_MASK;
++}
++
+ static void mark_jmp_point(struct bpf_verifier_env *env, int idx)
+ {
+ env->insn_aux_data[idx].jmp_point = true;
+@@ -3408,28 +3423,51 @@ static bool is_jmp_point(struct bpf_verifier_env *env, int insn_idx)
+ }
+
+ /* for any branch, call, exit record the history of jmps in the given state */
+-static int push_jmp_history(struct bpf_verifier_env *env,
+- struct bpf_verifier_state *cur)
++static int push_jmp_history(struct bpf_verifier_env *env, struct bpf_verifier_state *cur,
++ int insn_flags)
+ {
+ u32 cnt = cur->jmp_history_cnt;
+- struct bpf_idx_pair *p;
++ struct bpf_jmp_history_entry *p;
+ size_t alloc_size;
+
+- if (!is_jmp_point(env, env->insn_idx))
++ /* combine instruction flags if we already recorded this instruction */
++ if (env->cur_hist_ent) {
++ /* atomic instructions push insn_flags twice, for READ and
++ * WRITE sides, but they should agree on stack slot
++ */
++ WARN_ONCE((env->cur_hist_ent->flags & insn_flags) &&
++ (env->cur_hist_ent->flags & insn_flags) != insn_flags,
++ "verifier insn history bug: insn_idx %d cur flags %x new flags %x\n",
++ env->insn_idx, env->cur_hist_ent->flags, insn_flags);
++ env->cur_hist_ent->flags |= insn_flags;
+ return 0;
++ }
+
+ cnt++;
+ alloc_size = kmalloc_size_roundup(size_mul(cnt, sizeof(*p)));
+ p = krealloc(cur->jmp_history, alloc_size, GFP_USER);
+ if (!p)
+ return -ENOMEM;
+- p[cnt - 1].idx = env->insn_idx;
+- p[cnt - 1].prev_idx = env->prev_insn_idx;
+ cur->jmp_history = p;
++
++ p = &cur->jmp_history[cnt - 1];
++ p->idx = env->insn_idx;
++ p->prev_idx = env->prev_insn_idx;
++ p->flags = insn_flags;
+ cur->jmp_history_cnt = cnt;
++ env->cur_hist_ent = p;
++
+ return 0;
+ }
+
++static struct bpf_jmp_history_entry *get_jmp_hist_entry(struct bpf_verifier_state *st,
++ u32 hist_end, int insn_idx)
++{
++ if (hist_end > 0 && st->jmp_history[hist_end - 1].idx == insn_idx)
++ return &st->jmp_history[hist_end - 1];
++ return NULL;
++}
++
+ /* Backtrack one insn at a time. If idx is not at the top of recorded
+ * history then previous instruction came from straight line execution.
+ * Return -ENOENT if we exhausted all instructions within given state.
+@@ -3591,9 +3629,14 @@ static inline bool bt_is_reg_set(struct backtrack_state *bt, u32 reg)
+ return bt->reg_masks[bt->frame] & (1 << reg);
+ }
+
++static inline bool bt_is_frame_slot_set(struct backtrack_state *bt, u32 frame, u32 slot)
++{
++ return bt->stack_masks[frame] & (1ull << slot);
++}
++
+ static inline bool bt_is_slot_set(struct backtrack_state *bt, u32 slot)
+ {
+- return bt->stack_masks[bt->frame] & (1ull << slot);
++ return bt_is_frame_slot_set(bt, bt->frame, slot);
+ }
+
+ /* format registers bitmask, e.g., "r0,r2,r4" for 0x15 mask */
+@@ -3647,7 +3690,7 @@ static bool calls_callback(struct bpf_verifier_env *env, int insn_idx);
+ * - *was* processed previously during backtracking.
+ */
+ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
+- struct backtrack_state *bt)
++ struct bpf_jmp_history_entry *hist, struct backtrack_state *bt)
+ {
+ const struct bpf_insn_cbs cbs = {
+ .cb_call = disasm_kfunc_name,
+@@ -3660,7 +3703,7 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
+ u8 mode = BPF_MODE(insn->code);
+ u32 dreg = insn->dst_reg;
+ u32 sreg = insn->src_reg;
+- u32 spi, i;
++ u32 spi, i, fr;
+
+ if (insn->code == 0)
+ return 0;
+@@ -3723,20 +3766,15 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
+ * by 'precise' mark in corresponding register of this state.
+ * No further tracking necessary.
+ */
+- if (insn->src_reg != BPF_REG_FP)
++ if (!hist || !(hist->flags & INSN_F_STACK_ACCESS))
+ return 0;
+-
+ /* dreg = *(u64 *)[fp - off] was a fill from the stack.
+ * that [fp - off] slot contains scalar that needs to be
+ * tracked with precision
+ */
+- spi = (-insn->off - 1) / BPF_REG_SIZE;
+- if (spi >= 64) {
+- verbose(env, "BUG spi %d\n", spi);
+- WARN_ONCE(1, "verifier backtracking bug");
+- return -EFAULT;
+- }
+- bt_set_slot(bt, spi);
++ spi = insn_stack_access_spi(hist->flags);
++ fr = insn_stack_access_frameno(hist->flags);
++ bt_set_frame_slot(bt, fr, spi);
+ } else if (class == BPF_STX || class == BPF_ST) {
+ if (bt_is_reg_set(bt, dreg))
+ /* stx & st shouldn't be using _scalar_ dst_reg
+@@ -3745,17 +3783,13 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
+ */
+ return -ENOTSUPP;
+ /* scalars can only be spilled into stack */
+- if (insn->dst_reg != BPF_REG_FP)
++ if (!hist || !(hist->flags & INSN_F_STACK_ACCESS))
+ return 0;
+- spi = (-insn->off - 1) / BPF_REG_SIZE;
+- if (spi >= 64) {
+- verbose(env, "BUG spi %d\n", spi);
+- WARN_ONCE(1, "verifier backtracking bug");
+- return -EFAULT;
+- }
+- if (!bt_is_slot_set(bt, spi))
++ spi = insn_stack_access_spi(hist->flags);
++ fr = insn_stack_access_frameno(hist->flags);
++ if (!bt_is_frame_slot_set(bt, fr, spi))
+ return 0;
+- bt_clear_slot(bt, spi);
++ bt_clear_frame_slot(bt, fr, spi);
+ if (class == BPF_STX)
+ bt_set_reg(bt, sreg);
+ } else if (class == BPF_JMP || class == BPF_JMP32) {
+@@ -3799,10 +3833,14 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
+ WARN_ONCE(1, "verifier backtracking bug");
+ return -EFAULT;
+ }
+- /* we don't track register spills perfectly,
+- * so fallback to force-precise instead of failing */
+- if (bt_stack_mask(bt) != 0)
+- return -ENOTSUPP;
++ /* we are now tracking register spills correctly,
++ * so any instance of leftover slots is a bug
++ */
++ if (bt_stack_mask(bt) != 0) {
++ verbose(env, "BUG stack slots %llx\n", bt_stack_mask(bt));
++ WARN_ONCE(1, "verifier backtracking bug (subprog leftover stack slots)");
++ return -EFAULT;
++ }
+ /* propagate r1-r5 to the caller */
+ for (i = BPF_REG_1; i <= BPF_REG_5; i++) {
+ if (bt_is_reg_set(bt, i)) {
+@@ -3827,8 +3865,11 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
+ WARN_ONCE(1, "verifier backtracking bug");
+ return -EFAULT;
+ }
+- if (bt_stack_mask(bt) != 0)
+- return -ENOTSUPP;
++ if (bt_stack_mask(bt) != 0) {
++ verbose(env, "BUG stack slots %llx\n", bt_stack_mask(bt));
++ WARN_ONCE(1, "verifier backtracking bug (callback leftover stack slots)");
++ return -EFAULT;
++ }
+ /* clear r1-r5 in callback subprog's mask */
+ for (i = BPF_REG_1; i <= BPF_REG_5; i++)
+ bt_clear_reg(bt, i);
+@@ -4265,6 +4306,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
+ for (;;) {
+ DECLARE_BITMAP(mask, 64);
+ u32 history = st->jmp_history_cnt;
++ struct bpf_jmp_history_entry *hist;
+
+ if (env->log.level & BPF_LOG_LEVEL2) {
+ verbose(env, "mark_precise: frame%d: last_idx %d first_idx %d subseq_idx %d \n",
+@@ -4328,7 +4370,8 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
+ err = 0;
+ skip_first = false;
+ } else {
+- err = backtrack_insn(env, i, subseq_idx, bt);
++ hist = get_jmp_hist_entry(st, history, i);
++ err = backtrack_insn(env, i, subseq_idx, hist, bt);
+ }
+ if (err == -ENOTSUPP) {
+ mark_all_scalars_precise(env, env->cur_state);
+@@ -4381,22 +4424,10 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno)
+ bitmap_from_u64(mask, bt_frame_stack_mask(bt, fr));
+ for_each_set_bit(i, mask, 64) {
+ if (i >= func->allocated_stack / BPF_REG_SIZE) {
+- /* the sequence of instructions:
+- * 2: (bf) r3 = r10
+- * 3: (7b) *(u64 *)(r3 -8) = r0
+- * 4: (79) r4 = *(u64 *)(r10 -8)
+- * doesn't contain jmps. It's backtracked
+- * as a single block.
+- * During backtracking insn 3 is not recognized as
+- * stack access, so at the end of backtracking
+- * stack slot fp-8 is still marked in stack_mask.
+- * However the parent state may not have accessed
+- * fp-8 and it's "unallocated" stack space.
+- * In such case fallback to conservative.
+- */
+- mark_all_scalars_precise(env, env->cur_state);
+- bt_reset(bt);
+- return 0;
++ verbose(env, "BUG backtracking (stack slot %d, total slots %d)\n",
++ i, func->allocated_stack / BPF_REG_SIZE);
++ WARN_ONCE(1, "verifier backtracking bug (stack slot out of bounds)");
++ return -EFAULT;
+ }
+
+ if (!is_spilled_scalar_reg(&func->stack[i])) {
+@@ -4561,7 +4592,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+ int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err;
+ struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
+ struct bpf_reg_state *reg = NULL;
+- u32 dst_reg = insn->dst_reg;
++ int insn_flags = insn_stack_access_flags(state->frameno, spi);
+
+ /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0,
+ * so it's aligned access and [off, off + size) are within stack limits
+@@ -4599,17 +4630,6 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+ mark_stack_slot_scratched(env, spi);
+ if (reg && !(off % BPF_REG_SIZE) && register_is_bounded(reg) &&
+ !register_is_null(reg) && env->bpf_capable) {
+- if (dst_reg != BPF_REG_FP) {
+- /* The backtracking logic can only recognize explicit
+- * stack slot address like [fp - 8]. Other spill of
+- * scalar via different register has to be conservative.
+- * Backtrack from here and mark all registers as precise
+- * that contributed into 'reg' being a constant.
+- */
+- err = mark_chain_precision(env, value_regno);
+- if (err)
+- return err;
+- }
+ save_register_state(state, spi, reg, size);
+ /* Break the relation on a narrowing spill. */
+ if (fls64(reg->umax_value) > BITS_PER_BYTE * size)
+@@ -4621,6 +4641,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+ __mark_reg_known(&fake_reg, insn->imm);
+ fake_reg.type = SCALAR_VALUE;
+ save_register_state(state, spi, &fake_reg, size);
++ insn_flags = 0; /* not a register spill */
+ } else if (reg && is_spillable_regtype(reg->type)) {
+ /* register containing pointer is being spilled into stack */
+ if (size != BPF_REG_SIZE) {
+@@ -4666,9 +4687,12 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+
+ /* Mark slots affected by this stack write. */
+ for (i = 0; i < size; i++)
+- state->stack[spi].slot_type[(slot - i) % BPF_REG_SIZE] =
+- type;
++ state->stack[spi].slot_type[(slot - i) % BPF_REG_SIZE] = type;
++ insn_flags = 0; /* not a register spill */
+ }
++
++ if (insn_flags)
++ return push_jmp_history(env, env->cur_state, insn_flags);
+ return 0;
+ }
+
+@@ -4857,6 +4881,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+ int i, slot = -off - 1, spi = slot / BPF_REG_SIZE;
+ struct bpf_reg_state *reg;
+ u8 *stype, type;
++ int insn_flags = insn_stack_access_flags(reg_state->frameno, spi);
+
+ stype = reg_state->stack[spi].slot_type;
+ reg = &reg_state->stack[spi].spilled_ptr;
+@@ -4902,12 +4927,10 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+ return -EACCES;
+ }
+ mark_reg_unknown(env, state->regs, dst_regno);
++ insn_flags = 0; /* not restoring original register state */
+ }
+ state->regs[dst_regno].live |= REG_LIVE_WRITTEN;
+- return 0;
+- }
+-
+- if (dst_regno >= 0) {
++ } else if (dst_regno >= 0) {
+ /* restore register state from stack */
+ copy_register_state(&state->regs[dst_regno], reg);
+ /* mark reg as written since spilled pointer state likely
+@@ -4943,7 +4966,10 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+ mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64);
+ if (dst_regno >= 0)
+ mark_reg_stack_read(env, reg_state, off, off + size, dst_regno);
++ insn_flags = 0; /* we are not restoring spilled register */
+ }
++ if (insn_flags)
++ return push_jmp_history(env, env->cur_state, insn_flags);
+ return 0;
+ }
+
+@@ -7027,7 +7053,6 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
+ BPF_SIZE(insn->code), BPF_WRITE, -1, true, false);
+ if (err)
+ return err;
+-
+ return 0;
+ }
+
+@@ -16773,7 +16798,8 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
+ * the precision needs to be propagated back in
+ * the current state.
+ */
+- err = err ? : push_jmp_history(env, cur);
++ if (is_jmp_point(env, env->insn_idx))
++ err = err ? : push_jmp_history(env, cur, 0);
+ err = err ? : propagate_precision(env, &sl->state);
+ if (err)
+ return err;
+@@ -16997,6 +17023,9 @@ static int do_check(struct bpf_verifier_env *env)
+ u8 class;
+ int err;
+
++ /* reset current history entry on each new instruction */
++ env->cur_hist_ent = NULL;
++
+ env->prev_insn_idx = prev_insn_idx;
+ if (env->insn_idx >= insn_cnt) {
+ verbose(env, "invalid insn idx %d insn_cnt %d\n",
+@@ -17036,7 +17065,7 @@ static int do_check(struct bpf_verifier_env *env)
+ }
+
+ if (is_jmp_point(env, env->insn_idx)) {
+- err = push_jmp_history(env, state);
++ err = push_jmp_history(env, state, 0);
+ if (err)
+ return err;
+ }
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index b927f0623ac774..36097e8c904fe5 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -2096,8 +2096,10 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
+ if (ret)
+ goto exit_stats;
+
+- ret = cgroup_bpf_inherit(root_cgrp);
+- WARN_ON_ONCE(ret);
++ if (root == &cgrp_dfl_root) {
++ ret = cgroup_bpf_inherit(root_cgrp);
++ WARN_ON_ONCE(ret);
++ }
+
+ trace_cgroup_setup_root(root);
+
+@@ -2270,10 +2272,8 @@ static void cgroup_kill_sb(struct super_block *sb)
+ * And don't kill the default root.
+ */
+ if (list_empty(&root->cgrp.self.children) && root != &cgrp_dfl_root &&
+- !percpu_ref_is_dying(&root->cgrp.self.refcnt)) {
+- cgroup_bpf_offline(&root->cgrp);
++ !percpu_ref_is_dying(&root->cgrp.self.refcnt))
+ percpu_ref_kill(&root->cgrp.self.refcnt);
+- }
+ cgroup_put(&root->cgrp);
+ kernfs_kill_sb(sb);
+ }
+@@ -5618,9 +5618,11 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
+ if (ret)
+ goto out_kernfs_remove;
+
+- ret = cgroup_bpf_inherit(cgrp);
+- if (ret)
+- goto out_psi_free;
++ if (cgrp->root == &cgrp_dfl_root) {
++ ret = cgroup_bpf_inherit(cgrp);
++ if (ret)
++ goto out_psi_free;
++ }
+
+ /*
+ * New cgroup inherits effective freeze counter, and
+@@ -5938,7 +5940,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
+
+ cgroup1_check_for_release(parent);
+
+- cgroup_bpf_offline(cgrp);
++ if (cgrp->root == &cgrp_dfl_root)
++ cgroup_bpf_offline(cgrp);
+
+ /* put the base reference */
+ percpu_ref_kill(&cgrp->self.refcnt);
+diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
+index ed46d9e8c0e434..902575db9aec31 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -780,13 +780,15 @@ kfree_scale_init(void)
+ if (WARN_ON_ONCE(jiffies_at_lazy_cb - jif_start < 2 * HZ)) {
+ pr_alert("ERROR: call_rcu() CBs are not being lazy as expected!\n");
+ WARN_ON_ONCE(1);
+- return -1;
++ firsterr = -1;
++ goto unwind;
+ }
+
+ if (WARN_ON_ONCE(jiffies_at_lazy_cb - jif_start > 3 * HZ)) {
+ pr_alert("ERROR: call_rcu() CBs are being too lazy!\n");
+ WARN_ON_ONCE(1);
+- return -1;
++ firsterr = -1;
++ goto unwind;
+ }
+ }
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 3d7b119f6e2a36..fda08520c75c58 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -3150,7 +3150,7 @@ static int krc_count(struct kfree_rcu_cpu *krcp)
+ }
+
+ static void
+-schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
++__schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
+ {
+ long delay, delay_left;
+
+@@ -3164,6 +3164,16 @@ schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
+ queue_delayed_work(system_wq, &krcp->monitor_work, delay);
+ }
+
++static void
++schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
++{
++ unsigned long flags;
++
++ raw_spin_lock_irqsave(&krcp->lock, flags);
++ __schedule_delayed_monitor_work(krcp);
++ raw_spin_unlock_irqrestore(&krcp->lock, flags);
++}
++
+ static void
+ kvfree_rcu_drain_ready(struct kfree_rcu_cpu *krcp)
+ {
+@@ -3460,7 +3470,7 @@ void kvfree_call_rcu(struct rcu_head *head, void *ptr)
+
+ // Set timer to drain after KFREE_DRAIN_JIFFIES.
+ if (rcu_scheduler_active == RCU_SCHEDULER_RUNNING)
+- schedule_delayed_monitor_work(krcp);
++ __schedule_delayed_monitor_work(krcp);
+
+ unlock_return:
+ krc_this_cpu_unlock(krcp, flags);
+diff --git a/kernel/signal.c b/kernel/signal.c
+index 3808eaa2f49ab6..49c8c24b444d5e 100644
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -1996,14 +1996,15 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)
+ * into t->pending).
+ *
+ * Where type is not PIDTYPE_PID, signals must be delivered to the
+- * process. In this case, prefer to deliver to current if it is in
+- * the same thread group as the target process, which avoids
+- * unnecessarily waking up a potentially idle task.
++ * process. In this case, prefer to deliver to current if it is in the
++ * same thread group as the target process and its sighand is stable,
++ * which avoids unnecessarily waking up a potentially idle task.
+ */
+ t = pid_task(pid, type);
+ if (!t)
+ goto ret;
+- if (type != PIDTYPE_PID && same_thread_group(t, current))
++ if (type != PIDTYPE_PID &&
++ same_thread_group(t, current) && !current->exit_state)
+ t = current;
+ if (!likely(lock_task_sighand(t, &flags)))
+ goto ret;
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 642647f5046be0..1ad88e97b4ebcf 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -556,9 +556,9 @@ EXPORT_SYMBOL(ns_to_timespec64);
+ * - all other values are converted to jiffies by either multiplying
+ * the input value by a factor or dividing it with a factor and
+ * handling any 32-bit overflows.
+- * for the details see __msecs_to_jiffies()
++ * for the details see _msecs_to_jiffies()
+ *
+- * __msecs_to_jiffies() checks for the passed in value being a constant
++ * msecs_to_jiffies() checks for the passed in value being a constant
+ * via __builtin_constant_p() allowing gcc to eliminate most of the
+ * code, __msecs_to_jiffies() is called if the value passed does not
+ * allow constant folding and the actual conversion must be done at
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index 9064f75de7e468..e8fb6ada323c1a 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -3098,7 +3098,6 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe,
+ struct bpf_prog *prog = link->link.prog;
+ bool sleepable = prog->aux->sleepable;
+ struct bpf_run_ctx *old_run_ctx;
+- int err = 0;
+
+ if (link->task && current->mm != link->task->mm)
+ return 0;
+@@ -3111,7 +3110,7 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe,
+ migrate_disable();
+
+ old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
+- err = bpf_prog_run(link->link.prog, regs);
++ bpf_prog_run(link->link.prog, regs);
+ bpf_reset_run_ctx(old_run_ctx);
+
+ migrate_enable();
+@@ -3120,7 +3119,7 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe,
+ rcu_read_unlock_trace();
+ else
+ rcu_read_unlock();
+- return err;
++ return 0;
+ }
+
+ static bool
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 175eba24f5629a..1043936b352d12 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -4562,6 +4562,9 @@ ftrace_mod_callback(struct trace_array *tr, struct ftrace_hash *hash,
+ char *func;
+ int ret;
+
++ if (!tr)
++ return -ENODEV;
++
+ /* match_records() modifies func, and we need the original */
+ func = kstrdup(func_orig, GFP_KERNEL);
+ if (!func)
+diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
+index 05e7912418126b..3ff9caa4a71bbd 100644
+--- a/kernel/trace/trace_event_perf.c
++++ b/kernel/trace/trace_event_perf.c
+@@ -352,10 +352,16 @@ void perf_uprobe_destroy(struct perf_event *p_event)
+ int perf_trace_add(struct perf_event *p_event, int flags)
+ {
+ struct trace_event_call *tp_event = p_event->tp_event;
++ struct hw_perf_event *hwc = &p_event->hw;
+
+ if (!(flags & PERF_EF_START))
+ p_event->hw.state = PERF_HES_STOPPED;
+
++ if (is_sampling_event(p_event)) {
++ hwc->last_period = hwc->sample_period;
++ perf_swevent_set_period(p_event);
++ }
++
+ /*
+ * If TRACE_REG_PERF_ADD returns false; no custom action was performed
+ * and we need to take the default action of enqueueing our event on
+diff --git a/lib/maple_tree.c b/lib/maple_tree.c
+index 4e05511c8d1eba..4eda9490636024 100644
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -3547,9 +3547,20 @@ static inline int mas_root_expand(struct ma_state *mas, void *entry)
+ return slot;
+ }
+
++/*
++ * mas_store_root() - Storing value into root.
++ * @mas: The maple state
++ * @entry: The entry to store.
++ *
++ * There is no root node now and we are storing a value into the root - this
++ * function either assigns the pointer or expands into a node.
++ */
+ static inline void mas_store_root(struct ma_state *mas, void *entry)
+ {
+- if (likely((mas->last != 0) || (mas->index != 0)))
++ if (!entry) {
++ if (!mas->index)
++ rcu_assign_pointer(mas->tree->ma_root, NULL);
++ } else if (likely((mas->last != 0) || (mas->index != 0)))
+ mas_root_expand(mas, entry);
+ else if (((unsigned long) (entry) & 3) == 2)
+ mas_root_expand(mas, entry);
+diff --git a/lib/string_helpers.c b/lib/string_helpers.c
+index 9982344cca34d6..8f9f28dfdb3965 100644
+--- a/lib/string_helpers.c
++++ b/lib/string_helpers.c
+@@ -52,7 +52,7 @@ void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
+ static const unsigned int rounding[] = { 500, 50, 5 };
+ int i = 0, j;
+ u32 remainder = 0, sf_cap;
+- char tmp[8];
++ char tmp[12];
+ const char *unit;
+
+ tmp[0] = '\0';
+diff --git a/mm/internal.h b/mm/internal.h
+index a0b24d00557953..f773db493a99d0 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -40,7 +40,7 @@ struct folio_batch;
+ * when we specify __GFP_NOWARN.
+ */
+ #define WARN_ON_ONCE_GFP(cond, gfp) ({ \
+- static bool __section(".data.once") __warned; \
++ static bool __section(".data..once") __warned; \
+ int __ret_warn_once = !!(cond); \
+ \
+ if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \
+diff --git a/mm/slab.h b/mm/slab.h
+index 799a315695c679..62df6eeeb5ead7 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -78,6 +78,11 @@ struct slab {
+ struct {
+ unsigned inuse:16;
+ unsigned objects:15;
++ /*
++ * If slab debugging is enabled then the
++ * frozen bit can be reused to indicate
++ * that the slab was corrupted
++ */
+ unsigned frozen:1;
+ };
+ };
+diff --git a/mm/slub.c b/mm/slub.c
+index f7940048138c5a..d2544c88a5c43c 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -1275,6 +1275,11 @@ static int check_slab(struct kmem_cache *s, struct slab *slab)
+ slab->inuse, slab->objects);
+ return 0;
+ }
++ if (slab->frozen) {
++ slab_err(s, slab, "Slab disabled since SLUB metadata consistency check failed");
++ return 0;
++ }
++
+ /* Slab_pad_check fixes things up after itself */
+ slab_pad_check(s, slab);
+ return 1;
+@@ -1463,6 +1468,7 @@ static noinline bool alloc_debug_processing(struct kmem_cache *s,
+ slab_fix(s, "Marking all objects used");
+ slab->inuse = slab->objects;
+ slab->freelist = NULL;
++ slab->frozen = 1; /* mark consistency-failed slab as frozen */
+ }
+ return false;
+ }
+@@ -2162,7 +2168,8 @@ static void *alloc_single_from_partial(struct kmem_cache *s,
+ slab->inuse++;
+
+ if (!alloc_debug_processing(s, slab, object, orig_size)) {
+- remove_partial(n, slab);
++ if (folio_test_slab(slab_folio(slab)))
++ remove_partial(n, slab);
+ return NULL;
+ }
+
+diff --git a/mm/vmstat.c b/mm/vmstat.c
+index e9616c4ca12db8..57891697846b93 100644
+--- a/mm/vmstat.c
++++ b/mm/vmstat.c
+@@ -1723,6 +1723,7 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
+ zone_page_state(zone, i));
+
+ #ifdef CONFIG_NUMA
++ fold_vm_zone_numa_events(zone);
+ for (i = 0; i < NR_VM_NUMA_EVENT_ITEMS; i++)
+ seq_printf(m, "\n %-12s %lu", numa_stat_name(i),
+ zone_numa_event_state(zone, i));
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 1fffe2bed5b02f..6387ee924a2d61 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -287,7 +287,7 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
+ if (!priv->rings[i].intf)
+ break;
+ if (priv->rings[i].irq > 0)
+- unbind_from_irqhandler(priv->rings[i].irq, priv->dev);
++ unbind_from_irqhandler(priv->rings[i].irq, ring);
+ if (priv->rings[i].data.in) {
+ for (j = 0;
+ j < (1 << priv->rings[i].intf->ring_order);
+@@ -466,6 +466,7 @@ static int xen_9pfs_front_init(struct xenbus_device *dev)
+ goto error;
+ }
+
++ xenbus_switch_state(dev, XenbusStateInitialised);
+ return 0;
+
+ error_xenbus:
+@@ -513,8 +514,10 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev,
+ break;
+
+ case XenbusStateInitWait:
+- if (!xen_9pfs_front_init(dev))
+- xenbus_switch_state(dev, XenbusStateInitialised);
++ if (dev->state != XenbusStateInitialising)
++ break;
++
++ xen_9pfs_front_init(dev);
+ break;
+
+ case XenbusStateConnected:
+diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
+index 367e32fe30eb84..4b54dbbf0729a3 100644
+--- a/net/bluetooth/hci_sysfs.c
++++ b/net/bluetooth/hci_sysfs.c
+@@ -21,16 +21,6 @@ static const struct device_type bt_link = {
+ .release = bt_link_release,
+ };
+
+-/*
+- * The rfcomm tty device will possibly retain even when conn
+- * is down, and sysfs doesn't support move zombie device,
+- * so we should move the device before conn device is destroyed.
+- */
+-static int __match_tty(struct device *dev, void *data)
+-{
+- return !strncmp(dev_name(dev), "rfcomm", 6);
+-}
+-
+ void hci_conn_init_sysfs(struct hci_conn *conn)
+ {
+ struct hci_dev *hdev = conn->hdev;
+@@ -73,10 +63,13 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
+ return;
+ }
+
++ /* If there are devices using the connection as parent reset it to NULL
++ * before unregistering the device.
++ */
+ while (1) {
+ struct device *dev;
+
+- dev = device_find_child(&conn->dev, NULL, __match_tty);
++ dev = device_find_any_child(&conn->dev);
+ if (!dev)
+ break;
+ device_move(dev, NULL, DPM_ORDER_DEV_LAST);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 1f3a39c20a9114..1175248e4bec4b 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -1318,7 +1318,8 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
+ struct mgmt_mode *cp;
+
+ /* Make sure cmd still outstanding. */
+- if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
++ if (err == -ECANCELED ||
++ cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
+ return;
+
+ cp = cmd->param;
+@@ -1351,7 +1352,13 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
+ static int set_powered_sync(struct hci_dev *hdev, void *data)
+ {
+ struct mgmt_pending_cmd *cmd = data;
+- struct mgmt_mode *cp = cmd->param;
++ struct mgmt_mode *cp;
++
++ /* Make sure cmd still outstanding. */
++ if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
++ return -ECANCELED;
++
++ cp = cmd->param;
+
+ BT_DBG("%s", hdev->name);
+
+@@ -1503,7 +1510,8 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
+ bt_dev_dbg(hdev, "err %d", err);
+
+ /* Make sure cmd still outstanding. */
+- if (cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
++ if (err == -ECANCELED ||
++ cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
+ return;
+
+ hci_dev_lock(hdev);
+@@ -1677,7 +1685,8 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
+ bt_dev_dbg(hdev, "err %d", err);
+
+ /* Make sure cmd still outstanding. */
+- if (cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
++ if (err == -ECANCELED ||
++ cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
+ return;
+
+ hci_dev_lock(hdev);
+@@ -1910,7 +1919,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
+ bool changed;
+
+ /* Make sure cmd still outstanding. */
+- if (cmd != pending_find(MGMT_OP_SET_SSP, hdev))
++ if (err == -ECANCELED || cmd != pending_find(MGMT_OP_SET_SSP, hdev))
+ return;
+
+ if (err) {
+@@ -3775,7 +3784,8 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+
+ bt_dev_dbg(hdev, "err %d", err);
+
+- if (cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
++ if (err == -ECANCELED ||
++ cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
+ return;
+
+ if (status) {
+@@ -3950,7 +3960,8 @@ static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
+ struct sk_buff *skb = cmd->skb;
+ u8 status = mgmt_status(err);
+
+- if (cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
++ if (err == -ECANCELED ||
++ cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
+ return;
+
+ if (!status) {
+@@ -5841,13 +5852,16 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
+ {
+ struct mgmt_pending_cmd *cmd = data;
+
++ bt_dev_dbg(hdev, "err %d", err);
++
++ if (err == -ECANCELED)
++ return;
++
+ if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
+ cmd != pending_find(MGMT_OP_START_LIMITED_DISCOVERY, hdev) &&
+ cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
+ return;
+
+- bt_dev_dbg(hdev, "err %d", err);
+-
+ mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
+ cmd->param, 1);
+ mgmt_pending_remove(cmd);
+@@ -6080,7 +6094,8 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
+ {
+ struct mgmt_pending_cmd *cmd = data;
+
+- if (cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
++ if (err == -ECANCELED ||
++ cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
+ return;
+
+ bt_dev_dbg(hdev, "err %d", err);
+@@ -8025,7 +8040,8 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
+ u8 status = mgmt_status(err);
+ u16 eir_len;
+
+- if (cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
++ if (err == -ECANCELED ||
++ cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
+ return;
+
+ if (!status) {
+diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
+index cbff37b3273407..4fae82fedccaf9 100644
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -729,7 +729,8 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
+ struct sock *l2cap_sk;
+ struct l2cap_conn *conn;
+ struct rfcomm_conninfo cinfo;
+- int len, err = 0;
++ int err = 0;
++ size_t len;
+ u32 opt;
+
+ BT_DBG("sk %p", sk);
+@@ -783,7 +784,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
+ cinfo.hci_handle = conn->hcon->handle;
+ memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
+
+- len = min_t(unsigned int, len, sizeof(cinfo));
++ len = min(len, sizeof(cinfo));
+ if (copy_to_user(optval, (char *) &cinfo, len))
+ err = -EFAULT;
+
+@@ -802,7 +803,8 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
+ {
+ struct sock *sk = sock->sk;
+ struct bt_security sec;
+- int len, err = 0;
++ int err = 0;
++ size_t len;
+
+ BT_DBG("sk %p", sk);
+
+@@ -827,7 +829,7 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
+ sec.level = rfcomm_pi(sk)->sec_level;
+ sec.key_size = 0;
+
+- len = min_t(unsigned int, len, sizeof(sec));
++ len = min(len, sizeof(sec));
+ if (copy_to_user(optval, (char *) &sec, len))
+ err = -EFAULT;
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index f9d05eff80b17c..b64e7139eae19e 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2602,18 +2602,16 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes)
+
+ static void sk_msg_reset_curr(struct sk_msg *msg)
+ {
+- u32 i = msg->sg.start;
+- u32 len = 0;
+-
+- do {
+- len += sk_msg_elem(msg, i)->length;
+- sk_msg_iter_var_next(i);
+- if (len >= msg->sg.size)
+- break;
+- } while (i != msg->sg.end);
++ if (!msg->sg.size) {
++ msg->sg.curr = msg->sg.start;
++ msg->sg.copybreak = 0;
++ } else {
++ u32 i = msg->sg.end;
+
+- msg->sg.curr = i;
+- msg->sg.copybreak = 0;
++ sk_msg_iter_var_prev(i);
++ msg->sg.curr = i;
++ msg->sg.copybreak = msg->sg.data[i].length;
++ }
+ }
+
+ static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
+@@ -2776,7 +2774,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+ sk_msg_iter_var_next(i);
+ } while (i != msg->sg.end);
+
+- if (start >= offset + l)
++ if (start > offset + l)
+ return -EINVAL;
+
+ space = MAX_MSG_FRAGS - sk_msg_elem_used(msg);
+@@ -2801,6 +2799,8 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+
+ raw = page_address(page);
+
++ if (i == msg->sg.end)
++ sk_msg_iter_var_prev(i);
+ psge = sk_msg_elem(msg, i);
+ front = start - offset;
+ back = psge->length - front;
+@@ -2817,7 +2817,13 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+ }
+
+ put_page(sg_page(psge));
+- } else if (start - offset) {
++ new = i;
++ goto place_new;
++ }
++
++ if (start - offset) {
++ if (i == msg->sg.end)
++ sk_msg_iter_var_prev(i);
+ psge = sk_msg_elem(msg, i);
+ rsge = sk_msg_elem_cpy(msg, i);
+
+@@ -2828,39 +2834,44 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+ sk_msg_iter_var_next(i);
+ sg_unmark_end(psge);
+ sg_unmark_end(&rsge);
+- sk_msg_iter_next(msg, end);
+ }
+
+ /* Slot(s) to place newly allocated data */
++ sk_msg_iter_next(msg, end);
+ new = i;
++ sk_msg_iter_var_next(i);
++
++ if (i == msg->sg.end) {
++ if (!rsge.length)
++ goto place_new;
++ sk_msg_iter_next(msg, end);
++ goto place_new;
++ }
+
+ /* Shift one or two slots as needed */
+- if (!copy) {
+- sge = sk_msg_elem_cpy(msg, i);
++ sge = sk_msg_elem_cpy(msg, new);
++ sg_unmark_end(&sge);
+
++ nsge = sk_msg_elem_cpy(msg, i);
++ if (rsge.length) {
+ sk_msg_iter_var_next(i);
+- sg_unmark_end(&sge);
++ nnsge = sk_msg_elem_cpy(msg, i);
+ sk_msg_iter_next(msg, end);
++ }
+
+- nsge = sk_msg_elem_cpy(msg, i);
++ while (i != msg->sg.end) {
++ msg->sg.data[i] = sge;
++ sge = nsge;
++ sk_msg_iter_var_next(i);
+ if (rsge.length) {
+- sk_msg_iter_var_next(i);
++ nsge = nnsge;
+ nnsge = sk_msg_elem_cpy(msg, i);
+- }
+-
+- while (i != msg->sg.end) {
+- msg->sg.data[i] = sge;
+- sge = nsge;
+- sk_msg_iter_var_next(i);
+- if (rsge.length) {
+- nsge = nnsge;
+- nnsge = sk_msg_elem_cpy(msg, i);
+- } else {
+- nsge = sk_msg_elem_cpy(msg, i);
+- }
++ } else {
++ nsge = sk_msg_elem_cpy(msg, i);
+ }
+ }
+
++place_new:
+ /* Place newly allocated data buffer */
+ sk_mem_charge(msg->sk, len);
+ msg->sg.size += len;
+@@ -2889,8 +2900,10 @@ static const struct bpf_func_proto bpf_msg_push_data_proto = {
+
+ static void sk_msg_shift_left(struct sk_msg *msg, int i)
+ {
++ struct scatterlist *sge = sk_msg_elem(msg, i);
+ int prev;
+
++ put_page(sg_page(sge));
+ do {
+ prev = i;
+ sk_msg_iter_var_next(i);
+@@ -2927,6 +2940,9 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+ if (unlikely(flags))
+ return -EINVAL;
+
++ if (unlikely(len == 0))
++ return 0;
++
+ /* First find the starting scatterlist element */
+ i = msg->sg.start;
+ do {
+@@ -2939,7 +2955,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+ } while (i != msg->sg.end);
+
+ /* Bounds checks: start and pop must be inside message */
+- if (start >= offset + l || last >= msg->sg.size)
++ if (start >= offset + l || last > msg->sg.size)
+ return -EINVAL;
+
+ space = MAX_MSG_FRAGS - sk_msg_elem_used(msg);
+@@ -2968,12 +2984,12 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+ */
+ if (start != offset) {
+ struct scatterlist *nsge, *sge = sk_msg_elem(msg, i);
+- int a = start;
++ int a = start - offset;
+ int b = sge->length - pop - a;
+
+ sk_msg_iter_var_next(i);
+
+- if (pop < sge->length - a) {
++ if (b > 0) {
+ if (space) {
+ sge->length = a;
+ sk_msg_shift_right(msg, i);
+@@ -2992,7 +3008,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+ if (unlikely(!page))
+ return -ENOMEM;
+
+- sge->length = a;
+ orig = sg_page(sge);
+ from = sg_virt(sge);
+ to = page_address(page);
+@@ -3002,7 +3017,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+ put_page(orig);
+ }
+ pop = 0;
+- } else if (pop >= sge->length - a) {
++ } else {
+ pop -= (sge->length - a);
+ sge->length = a;
+ }
+@@ -3036,7 +3051,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+ pop -= sge->length;
+ sk_msg_shift_left(msg, i);
+ }
+- sk_msg_iter_var_next(i);
+ }
+
+ sk_mem_uncharge(msg->sk, len - pop);
+diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
+index fae9c4694186ea..412816076b8bc5 100644
+--- a/net/core/gen_estimator.c
++++ b/net/core/gen_estimator.c
+@@ -206,7 +206,7 @@ void gen_kill_estimator(struct net_rate_estimator __rcu **rate_est)
+ {
+ struct net_rate_estimator *est;
+
+- est = xchg((__force struct net_rate_estimator **)rate_est, NULL);
++ est = unrcu_pointer(xchg(rate_est, NULL));
+ if (est) {
+ timer_shutdown_sync(&est->timer);
+ kfree_rcu(est, rcu);
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index bbf40b99971382..846fd672f0e529 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -1117,9 +1117,9 @@ static void sk_psock_strp_data_ready(struct sock *sk)
+ if (tls_sw_has_ctx_rx(sk)) {
+ psock->saved_data_ready(sk);
+ } else {
+- write_lock_bh(&sk->sk_callback_lock);
++ read_lock_bh(&sk->sk_callback_lock);
+ strp_data_ready(&psock->strp);
+- write_unlock_bh(&sk->sk_callback_lock);
++ read_unlock_bh(&sk->sk_callback_lock);
+ }
+ }
+ rcu_read_unlock();
+diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
+index c53b731f2d6728..70007fc578a136 100644
+--- a/net/core/sock_diag.c
++++ b/net/core/sock_diag.c
+@@ -16,9 +16,10 @@
+ #include <linux/inet_diag.h>
+ #include <linux/sock_diag.h>
+
+-static const struct sock_diag_handler *sock_diag_handlers[AF_MAX];
+-static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh);
+-static DEFINE_MUTEX(sock_diag_table_mutex);
++static const struct sock_diag_handler __rcu *sock_diag_handlers[AF_MAX];
++
++static const struct sock_diag_inet_compat __rcu *inet_rcv_compat;
++
+ static struct workqueue_struct *broadcast_wq;
+
+ DEFINE_COOKIE(sock_cookie);
+@@ -122,6 +123,24 @@ static size_t sock_diag_nlmsg_size(void)
+ + nla_total_size_64bit(sizeof(struct tcp_info))); /* INET_DIAG_INFO */
+ }
+
++static const struct sock_diag_handler *sock_diag_lock_handler(int family)
++{
++ const struct sock_diag_handler *handler;
++
++ rcu_read_lock();
++ handler = rcu_dereference(sock_diag_handlers[family]);
++ if (handler && !try_module_get(handler->owner))
++ handler = NULL;
++ rcu_read_unlock();
++
++ return handler;
++}
++
++static void sock_diag_unlock_handler(const struct sock_diag_handler *handler)
++{
++ module_put(handler->owner);
++}
++
+ static void sock_diag_broadcast_destroy_work(struct work_struct *work)
+ {
+ struct broadcast_sk *bsk =
+@@ -138,12 +157,12 @@ static void sock_diag_broadcast_destroy_work(struct work_struct *work)
+ if (!skb)
+ goto out;
+
+- mutex_lock(&sock_diag_table_mutex);
+- hndl = sock_diag_handlers[sk->sk_family];
+- if (hndl && hndl->get_info)
+- err = hndl->get_info(skb, sk);
+- mutex_unlock(&sock_diag_table_mutex);
+-
++ hndl = sock_diag_lock_handler(sk->sk_family);
++ if (hndl) {
++ if (hndl->get_info)
++ err = hndl->get_info(skb, sk);
++ sock_diag_unlock_handler(hndl);
++ }
+ if (!err)
+ nlmsg_multicast(sock_net(sk)->diag_nlsk, skb, 0, group,
+ GFP_KERNEL);
+@@ -166,51 +185,43 @@ void sock_diag_broadcast_destroy(struct sock *sk)
+ queue_work(broadcast_wq, &bsk->work);
+ }
+
+-void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
++void sock_diag_register_inet_compat(const struct sock_diag_inet_compat *ptr)
+ {
+- mutex_lock(&sock_diag_table_mutex);
+- inet_rcv_compat = fn;
+- mutex_unlock(&sock_diag_table_mutex);
++ xchg(&inet_rcv_compat, RCU_INITIALIZER(ptr));
+ }
+ EXPORT_SYMBOL_GPL(sock_diag_register_inet_compat);
+
+-void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
++void sock_diag_unregister_inet_compat(const struct sock_diag_inet_compat *ptr)
+ {
+- mutex_lock(&sock_diag_table_mutex);
+- inet_rcv_compat = NULL;
+- mutex_unlock(&sock_diag_table_mutex);
++ const struct sock_diag_inet_compat *old;
++
++ old = unrcu_pointer(xchg(&inet_rcv_compat, NULL));
++ WARN_ON_ONCE(old != ptr);
+ }
+ EXPORT_SYMBOL_GPL(sock_diag_unregister_inet_compat);
+
+ int sock_diag_register(const struct sock_diag_handler *hndl)
+ {
+- int err = 0;
++ int family = hndl->family;
+
+- if (hndl->family >= AF_MAX)
++ if (family >= AF_MAX)
+ return -EINVAL;
+
+- mutex_lock(&sock_diag_table_mutex);
+- if (sock_diag_handlers[hndl->family])
+- err = -EBUSY;
+- else
+- WRITE_ONCE(sock_diag_handlers[hndl->family], hndl);
+- mutex_unlock(&sock_diag_table_mutex);
+-
+- return err;
++ return !cmpxchg((const struct sock_diag_handler **)
++ &sock_diag_handlers[family],
++ NULL, hndl) ? 0 : -EBUSY;
+ }
+ EXPORT_SYMBOL_GPL(sock_diag_register);
+
+-void sock_diag_unregister(const struct sock_diag_handler *hnld)
++void sock_diag_unregister(const struct sock_diag_handler *hndl)
+ {
+- int family = hnld->family;
++ int family = hndl->family;
+
+ if (family >= AF_MAX)
+ return;
+
+- mutex_lock(&sock_diag_table_mutex);
+- BUG_ON(sock_diag_handlers[family] != hnld);
+- WRITE_ONCE(sock_diag_handlers[family], NULL);
+- mutex_unlock(&sock_diag_table_mutex);
++ xchg((const struct sock_diag_handler **)&sock_diag_handlers[family],
++ NULL);
+ }
+ EXPORT_SYMBOL_GPL(sock_diag_unregister);
+
+@@ -227,20 +238,20 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
+ return -EINVAL;
+ req->sdiag_family = array_index_nospec(req->sdiag_family, AF_MAX);
+
+- if (READ_ONCE(sock_diag_handlers[req->sdiag_family]) == NULL)
++ if (!rcu_access_pointer(sock_diag_handlers[req->sdiag_family]))
+ sock_load_diag_module(req->sdiag_family, 0);
+
+- mutex_lock(&sock_diag_table_mutex);
+- hndl = sock_diag_handlers[req->sdiag_family];
++ hndl = sock_diag_lock_handler(req->sdiag_family);
+ if (hndl == NULL)
+- err = -ENOENT;
+- else if (nlh->nlmsg_type == SOCK_DIAG_BY_FAMILY)
++ return -ENOENT;
++
++ if (nlh->nlmsg_type == SOCK_DIAG_BY_FAMILY)
+ err = hndl->dump(skb, nlh);
+ else if (nlh->nlmsg_type == SOCK_DESTROY && hndl->destroy)
+ err = hndl->destroy(skb, nlh);
+ else
+ err = -EOPNOTSUPP;
+- mutex_unlock(&sock_diag_table_mutex);
++ sock_diag_unlock_handler(hndl);
+
+ return err;
+ }
+@@ -248,20 +259,27 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
+ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack)
+ {
++ const struct sock_diag_inet_compat *ptr;
+ int ret;
+
+ switch (nlh->nlmsg_type) {
+ case TCPDIAG_GETSOCK:
+ case DCCPDIAG_GETSOCK:
+- if (inet_rcv_compat == NULL)
++
++ if (!rcu_access_pointer(inet_rcv_compat))
+ sock_load_diag_module(AF_INET, 0);
+
+- mutex_lock(&sock_diag_table_mutex);
+- if (inet_rcv_compat != NULL)
+- ret = inet_rcv_compat(skb, nlh);
+- else
+- ret = -EOPNOTSUPP;
+- mutex_unlock(&sock_diag_table_mutex);
++ rcu_read_lock();
++ ptr = rcu_dereference(inet_rcv_compat);
++ if (ptr && !try_module_get(ptr->owner))
++ ptr = NULL;
++ rcu_read_unlock();
++
++ ret = -EOPNOTSUPP;
++ if (ptr) {
++ ret = ptr->fn(skb, nlh);
++ module_put(ptr->owner);
++ }
+
+ return ret;
+ case SOCK_DIAG_BY_FAMILY:
+@@ -286,12 +304,12 @@ static int sock_diag_bind(struct net *net, int group)
+ switch (group) {
+ case SKNLGRP_INET_TCP_DESTROY:
+ case SKNLGRP_INET_UDP_DESTROY:
+- if (!READ_ONCE(sock_diag_handlers[AF_INET]))
++ if (!rcu_access_pointer(sock_diag_handlers[AF_INET]))
+ sock_load_diag_module(AF_INET, 0);
+ break;
+ case SKNLGRP_INET6_TCP_DESTROY:
+ case SKNLGRP_INET6_UDP_DESTROY:
+- if (!READ_ONCE(sock_diag_handlers[AF_INET6]))
++ if (!rcu_access_pointer(sock_diag_handlers[AF_INET6]))
+ sock_load_diag_module(AF_INET6, 0);
+ break;
+ }
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index c5f7bd01379ce3..906c38b9d66ff3 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -253,6 +253,8 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master)
+ skb->dev = master->dev;
+ skb->priority = TC_PRIO_CONTROL;
+
++ skb_reset_network_header(skb);
++ skb_reset_transport_header(skb);
+ if (dev_hard_header(skb, skb->dev, ETH_P_PRP,
+ hsr->sup_multicast_addr,
+ skb->dev->dev_addr, skb->len) <= 0)
+@@ -260,8 +262,6 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master)
+
+ skb_reset_mac_header(skb);
+ skb_reset_mac_len(skb);
+- skb_reset_network_header(skb);
+- skb_reset_transport_header(skb);
+
+ return skb;
+ out:
+diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
+index 685474ef11c400..8daa6418e25a0d 100644
+--- a/net/ipv4/cipso_ipv4.c
++++ b/net/ipv4/cipso_ipv4.c
+@@ -1955,7 +1955,7 @@ int cipso_v4_req_setattr(struct request_sock *req,
+ buf = NULL;
+
+ req_inet = inet_rsk(req);
+- opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt);
++ opt = unrcu_pointer(xchg(&req_inet->ireq_opt, RCU_INITIALIZER(opt)));
+ if (opt)
+ kfree_rcu(opt, rcu);
+
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index ca8cc0988b618c..bd032ac2376ed7 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -1124,7 +1124,7 @@ static void reqsk_timer_handler(struct timer_list *t)
+
+ drop:
+ __inet_csk_reqsk_queue_drop(sk_listener, oreq, true);
+- reqsk_put(req);
++ reqsk_put(oreq);
+ }
+
+ static bool reqsk_queue_hash_req(struct request_sock *req,
+diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
+index 87ecefea72398d..5d09ab3ed735e9 100644
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -1397,6 +1397,7 @@ int inet_diag_handler_get_info(struct sk_buff *skb, struct sock *sk)
+ }
+
+ static const struct sock_diag_handler inet_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_INET,
+ .dump = inet_diag_handler_cmd,
+ .get_info = inet_diag_handler_get_info,
+@@ -1404,6 +1405,7 @@ static const struct sock_diag_handler inet_diag_handler = {
+ };
+
+ static const struct sock_diag_handler inet6_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_INET6,
+ .dump = inet_diag_handler_cmd,
+ .get_info = inet_diag_handler_get_info,
+@@ -1443,6 +1445,11 @@ void inet_diag_unregister(const struct inet_diag_handler *h)
+ }
+ EXPORT_SYMBOL_GPL(inet_diag_unregister);
+
++static const struct sock_diag_inet_compat inet_diag_compat = {
++ .owner = THIS_MODULE,
++ .fn = inet_diag_rcv_msg_compat,
++};
++
+ static int __init inet_diag_init(void)
+ {
+ const int inet_diag_table_size = (IPPROTO_MAX *
+@@ -1461,7 +1468,7 @@ static int __init inet_diag_init(void)
+ if (err)
+ goto out_free_inet;
+
+- sock_diag_register_inet_compat(inet_diag_rcv_msg_compat);
++ sock_diag_register_inet_compat(&inet_diag_compat);
+ out:
+ return err;
+
+@@ -1476,7 +1483,7 @@ static void __exit inet_diag_exit(void)
+ {
+ sock_diag_unregister(&inet6_diag_handler);
+ sock_diag_unregister(&inet_diag_handler);
+- sock_diag_unregister_inet_compat(inet_diag_rcv_msg_compat);
++ sock_diag_unregister_inet_compat(&inet_diag_compat);
+ kfree(inet_diag_table);
+ }
+
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index 66eade3fb629f1..dc0ad979a894ab 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -136,7 +136,7 @@ static struct mr_table *ipmr_mr_table_iter(struct net *net,
+ return ret;
+ }
+
+-static struct mr_table *ipmr_get_table(struct net *net, u32 id)
++static struct mr_table *__ipmr_get_table(struct net *net, u32 id)
+ {
+ struct mr_table *mrt;
+
+@@ -147,6 +147,16 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
+ return NULL;
+ }
+
++static struct mr_table *ipmr_get_table(struct net *net, u32 id)
++{
++ struct mr_table *mrt;
++
++ rcu_read_lock();
++ mrt = __ipmr_get_table(net, id);
++ rcu_read_unlock();
++ return mrt;
++}
++
+ static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4,
+ struct mr_table **mrt)
+ {
+@@ -188,7 +198,7 @@ static int ipmr_rule_action(struct fib_rule *rule, struct flowi *flp,
+
+ arg->table = fib_rule_get_table(rule, arg);
+
+- mrt = ipmr_get_table(rule->fr_net, arg->table);
++ mrt = __ipmr_get_table(rule->fr_net, arg->table);
+ if (!mrt)
+ return -EAGAIN;
+ res->mrt = mrt;
+@@ -314,6 +324,8 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
+ return net->ipv4.mrt;
+ }
+
++#define __ipmr_get_table ipmr_get_table
++
+ static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4,
+ struct mr_table **mrt)
+ {
+@@ -402,7 +414,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
+ if (id != RT_TABLE_DEFAULT && id >= 1000000000)
+ return ERR_PTR(-EINVAL);
+
+- mrt = ipmr_get_table(net, id);
++ mrt = __ipmr_get_table(net, id);
+ if (mrt)
+ return mrt;
+
+@@ -1373,7 +1385,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval,
+ goto out_unlock;
+ }
+
+- mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
++ mrt = __ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
+ if (!mrt) {
+ ret = -ENOENT;
+ goto out_unlock;
+@@ -2261,11 +2273,13 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
+ struct mr_table *mrt;
+ int err;
+
+- mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
+- if (!mrt)
++ rcu_read_lock();
++ mrt = __ipmr_get_table(net, RT_TABLE_DEFAULT);
++ if (!mrt) {
++ rcu_read_unlock();
+ return -ENOENT;
++ }
+
+- rcu_read_lock();
+ cache = ipmr_cache_find(mrt, saddr, daddr);
+ if (!cache && skb->dev) {
+ int vif = ipmr_find_vif(mrt, skb->dev);
+@@ -2550,7 +2564,7 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+ grp = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0;
+ tableid = tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : 0;
+
+- mrt = ipmr_get_table(net, tableid ? tableid : RT_TABLE_DEFAULT);
++ mrt = __ipmr_get_table(net, tableid ? tableid : RT_TABLE_DEFAULT);
+ if (!mrt) {
+ err = -ENOENT;
+ goto errout_free;
+@@ -2602,7 +2616,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
+ if (filter.table_id) {
+ struct mr_table *mrt;
+
+- mrt = ipmr_get_table(sock_net(skb->sk), filter.table_id);
++ mrt = __ipmr_get_table(sock_net(skb->sk), filter.table_id);
+ if (!mrt) {
+ if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR)
+ return skb->len;
+@@ -2710,7 +2724,7 @@ static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh,
+ break;
+ }
+ }
+- mrt = ipmr_get_table(net, tblid);
++ mrt = __ipmr_get_table(net, tblid);
+ if (!mrt) {
+ ret = -ENOENT;
+ goto out;
+@@ -2918,13 +2932,15 @@ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+ struct net *net = seq_file_net(seq);
+ struct mr_table *mrt;
+
+- mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
+- if (!mrt)
++ rcu_read_lock();
++ mrt = __ipmr_get_table(net, RT_TABLE_DEFAULT);
++ if (!mrt) {
++ rcu_read_unlock();
+ return ERR_PTR(-ENOENT);
++ }
+
+ iter->mrt = mrt;
+
+- rcu_read_lock();
+ return mr_vif_seq_start(seq, pos);
+ }
+
+diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c
+index 271dc03fc6dbd9..f0af12a2f70bcd 100644
+--- a/net/ipv4/ipmr_base.c
++++ b/net/ipv4/ipmr_base.c
+@@ -310,7 +310,8 @@ int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
+ if (filter->filter_set)
+ flags |= NLM_F_DUMP_FILTERED;
+
+- list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
++ list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list,
++ lockdep_rtnl_is_held()) {
+ if (e < s_e)
+ goto next_entry;
+ if (filter->dev &&
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 75371928d94f6e..5e6615f69f175d 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3065,7 +3065,7 @@ int tcp_disconnect(struct sock *sk, int flags)
+ icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
+ memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
+ __sk_dst_reset(sk);
+- dst_release(xchg((__force struct dst_entry **)&sk->sk_rx_dst, NULL));
++ dst_release(unrcu_pointer(xchg(&sk->sk_rx_dst, NULL)));
+ tcp_saved_syn_free(tp);
+ tp->compressed_ack = 0;
+ tp->segs_in = 0;
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index fe6178715ba05f..915286c3615a27 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -221,11 +221,11 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
+ int flags,
+ int *addr_len)
+ {
+- struct tcp_sock *tcp = tcp_sk(sk);
+ int peek = flags & MSG_PEEK;
+- u32 seq = tcp->copied_seq;
+ struct sk_psock *psock;
++ struct tcp_sock *tcp;
+ int copied = 0;
++ u32 seq;
+
+ if (unlikely(flags & MSG_ERRQUEUE))
+ return inet_recv_error(sk, msg, len, addr_len);
+@@ -238,7 +238,8 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
+ return tcp_recvmsg(sk, msg, len, flags, addr_len);
+
+ lock_sock(sk);
+-
++ tcp = tcp_sk(sk);
++ seq = tcp->copied_seq;
+ /* We may have received data on the sk_receive_queue pre-accept and
+ * then we can not use read_skb in this context because we haven't
+ * assigned a sk_socket yet so have no link to the ops. The work-around
+diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
+index 8ed54e7334a9c6..0f523cbfe329ef 100644
+--- a/net/ipv4/tcp_fastopen.c
++++ b/net/ipv4/tcp_fastopen.c
+@@ -49,7 +49,7 @@ void tcp_fastopen_ctx_destroy(struct net *net)
+ {
+ struct tcp_fastopen_context *ctxt;
+
+- ctxt = xchg((__force struct tcp_fastopen_context **)&net->ipv4.tcp_fastopen_ctx, NULL);
++ ctxt = unrcu_pointer(xchg(&net->ipv4.tcp_fastopen_ctx, NULL));
+
+ if (ctxt)
+ call_rcu(&ctxt->rcu, tcp_fastopen_ctx_free);
+@@ -80,9 +80,10 @@ int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
+
+ if (sk) {
+ q = &inet_csk(sk)->icsk_accept_queue.fastopenq;
+- octx = xchg((__force struct tcp_fastopen_context **)&q->ctx, ctx);
++ octx = unrcu_pointer(xchg(&q->ctx, RCU_INITIALIZER(ctx)));
+ } else {
+- octx = xchg((__force struct tcp_fastopen_context **)&net->ipv4.tcp_fastopen_ctx, ctx);
++ octx = unrcu_pointer(xchg(&net->ipv4.tcp_fastopen_ctx,
++ RCU_INITIALIZER(ctx)));
+ }
+
+ if (octx)
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 73fb814460b6b7..2e4e5356039480 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2232,7 +2232,7 @@ bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
+ struct dst_entry *old;
+
+ if (dst_hold_safe(dst)) {
+- old = xchg((__force struct dst_entry **)&sk->sk_rx_dst, dst);
++ old = unrcu_pointer(xchg(&sk->sk_rx_dst, RCU_INITIALIZER(dst)));
+ dst_release(old);
+ return old != dst;
+ }
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index a9358c796a8150..8360939acf85ad 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -2535,6 +2535,24 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
+ return idev;
+ }
+
++static void delete_tempaddrs(struct inet6_dev *idev,
++ struct inet6_ifaddr *ifp)
++{
++ struct inet6_ifaddr *ift, *tmp;
++
++ write_lock_bh(&idev->lock);
++ list_for_each_entry_safe(ift, tmp, &idev->tempaddr_list, tmp_list) {
++ if (ift->ifpub != ifp)
++ continue;
++
++ in6_ifa_hold(ift);
++ write_unlock_bh(&idev->lock);
++ ipv6_del_addr(ift);
++ write_lock_bh(&idev->lock);
++ }
++ write_unlock_bh(&idev->lock);
++}
++
+ static void manage_tempaddrs(struct inet6_dev *idev,
+ struct inet6_ifaddr *ifp,
+ __u32 valid_lft, __u32 prefered_lft,
+@@ -3076,11 +3094,12 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
+ in6_ifa_hold(ifp);
+ read_unlock_bh(&idev->lock);
+
+- if (!(ifp->flags & IFA_F_TEMPORARY) &&
+- (ifa_flags & IFA_F_MANAGETEMPADDR))
+- manage_tempaddrs(idev, ifp, 0, 0, false,
+- jiffies);
+ ipv6_del_addr(ifp);
++
++ if (!(ifp->flags & IFA_F_TEMPORARY) &&
++ (ifp->flags & IFA_F_MANAGETEMPADDR))
++ delete_tempaddrs(idev, ifp);
++
+ addrconf_verify_rtnl(net);
+ if (ipv6_addr_is_multicast(pfx)) {
+ ipv6_mc_config(net->ipv6.mc_autojoin_sk,
+@@ -4891,14 +4910,12 @@ static int inet6_addr_modify(struct net *net, struct inet6_ifaddr *ifp,
+ }
+
+ if (was_managetempaddr || ifp->flags & IFA_F_MANAGETEMPADDR) {
+- if (was_managetempaddr &&
+- !(ifp->flags & IFA_F_MANAGETEMPADDR)) {
+- cfg->valid_lft = 0;
+- cfg->preferred_lft = 0;
+- }
+- manage_tempaddrs(ifp->idev, ifp, cfg->valid_lft,
+- cfg->preferred_lft, !was_managetempaddr,
+- jiffies);
++ if (was_managetempaddr && !(ifp->flags & IFA_F_MANAGETEMPADDR))
++ delete_tempaddrs(ifp->idev, ifp);
++ else
++ manage_tempaddrs(ifp->idev, ifp, cfg->valid_lft,
++ cfg->preferred_lft, !was_managetempaddr,
++ jiffies);
+ }
+
+ addrconf_verify_rtnl(net);
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index b9c50cceba568c..99843eb4d49b9a 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -507,7 +507,7 @@ void inet6_cleanup_sock(struct sock *sk)
+
+ /* Free tx options */
+
+- opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL);
++ opt = unrcu_pointer(xchg(&np->opt, NULL));
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index 4356806b52bd51..afa9073567dc40 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -982,7 +982,7 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh,
+ if (pcpu_rt && rcu_access_pointer(pcpu_rt->from) == match) {
+ struct fib6_info *from;
+
+- from = xchg((__force struct fib6_info **)&pcpu_rt->from, NULL);
++ from = unrcu_pointer(xchg(&pcpu_rt->from, NULL));
+ fib6_info_release(from);
+ }
+ }
+diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
+index 30ca064b76ef17..e24fa0843c7d11 100644
+--- a/net/ipv6/ip6mr.c
++++ b/net/ipv6/ip6mr.c
+@@ -125,7 +125,7 @@ static struct mr_table *ip6mr_mr_table_iter(struct net *net,
+ return ret;
+ }
+
+-static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
++static struct mr_table *__ip6mr_get_table(struct net *net, u32 id)
+ {
+ struct mr_table *mrt;
+
+@@ -136,6 +136,16 @@ static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
+ return NULL;
+ }
+
++static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
++{
++ struct mr_table *mrt;
++
++ rcu_read_lock();
++ mrt = __ip6mr_get_table(net, id);
++ rcu_read_unlock();
++ return mrt;
++}
++
+ static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
+ struct mr_table **mrt)
+ {
+@@ -177,7 +187,7 @@ static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
+
+ arg->table = fib_rule_get_table(rule, arg);
+
+- mrt = ip6mr_get_table(rule->fr_net, arg->table);
++ mrt = __ip6mr_get_table(rule->fr_net, arg->table);
+ if (!mrt)
+ return -EAGAIN;
+ res->mrt = mrt;
+@@ -304,6 +314,8 @@ static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
+ return net->ipv6.mrt6;
+ }
+
++#define __ip6mr_get_table ip6mr_get_table
++
+ static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
+ struct mr_table **mrt)
+ {
+@@ -382,7 +394,7 @@ static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
+ {
+ struct mr_table *mrt;
+
+- mrt = ip6mr_get_table(net, id);
++ mrt = __ip6mr_get_table(net, id);
+ if (mrt)
+ return mrt;
+
+@@ -411,13 +423,15 @@ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+ struct net *net = seq_file_net(seq);
+ struct mr_table *mrt;
+
+- mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
+- if (!mrt)
++ rcu_read_lock();
++ mrt = __ip6mr_get_table(net, RT6_TABLE_DFLT);
++ if (!mrt) {
++ rcu_read_unlock();
+ return ERR_PTR(-ENOENT);
++ }
+
+ iter->mrt = mrt;
+
+- rcu_read_lock();
+ return mr_vif_seq_start(seq, pos);
+ }
+
+@@ -2278,11 +2292,13 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
+ struct mfc6_cache *cache;
+ struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
+
+- mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
+- if (!mrt)
++ rcu_read_lock();
++ mrt = __ip6mr_get_table(net, RT6_TABLE_DFLT);
++ if (!mrt) {
++ rcu_read_unlock();
+ return -ENOENT;
++ }
+
+- rcu_read_lock();
+ cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
+ if (!cache && skb->dev) {
+ int vif = ip6mr_find_vif(mrt, skb->dev);
+@@ -2563,7 +2579,7 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+ grp = nla_get_in6_addr(tb[RTA_DST]);
+ tableid = tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : 0;
+
+- mrt = ip6mr_get_table(net, tableid ?: RT_TABLE_DEFAULT);
++ mrt = __ip6mr_get_table(net, tableid ?: RT_TABLE_DEFAULT);
+ if (!mrt) {
+ NL_SET_ERR_MSG_MOD(extack, "MR table does not exist");
+ return -ENOENT;
+@@ -2608,7 +2624,7 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
+ if (filter.table_id) {
+ struct mr_table *mrt;
+
+- mrt = ip6mr_get_table(sock_net(skb->sk), filter.table_id);
++ mrt = __ip6mr_get_table(sock_net(skb->sk), filter.table_id);
+ if (!mrt) {
+ if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IP6MR)
+ return skb->len;
+diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
+index 0e2a0847b387f0..f106b19b74dd79 100644
+--- a/net/ipv6/ipv6_sockglue.c
++++ b/net/ipv6/ipv6_sockglue.c
+@@ -111,8 +111,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
+ icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
+ }
+ }
+- opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
+- opt);
++ opt = unrcu_pointer(xchg(&inet6_sk(sk)->opt, RCU_INITIALIZER(opt)));
+ sk_dst_reset(sk);
+
+ return opt;
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index a9104c4c1c02d9..e320dfa7fe7fc7 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -368,7 +368,7 @@ static void ip6_dst_destroy(struct dst_entry *dst)
+ in6_dev_put(idev);
+ }
+
+- from = xchg((__force struct fib6_info **)&rt->from, NULL);
++ from = unrcu_pointer(xchg(&rt->from, NULL));
+ fib6_info_release(from);
+ }
+
+@@ -376,6 +376,7 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
+ {
+ struct rt6_info *rt = (struct rt6_info *)dst;
+ struct inet6_dev *idev = rt->rt6i_idev;
++ struct fib6_info *from;
+
+ if (idev && idev->dev != blackhole_netdev) {
+ struct inet6_dev *blackhole_idev = in6_dev_get(blackhole_netdev);
+@@ -385,6 +386,8 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
+ in6_dev_put(idev);
+ }
+ }
++ from = unrcu_pointer(xchg(&rt->from, NULL));
++ fib6_info_release(from);
+ }
+
+ static bool __rt6_check_expired(const struct rt6_info *rt)
+@@ -1430,7 +1433,7 @@ static struct rt6_info *rt6_make_pcpu_route(struct net *net,
+ if (res->f6i->fib6_destroying) {
+ struct fib6_info *from;
+
+- from = xchg((__force struct fib6_info **)&pcpu_rt->from, NULL);
++ from = unrcu_pointer(xchg(&pcpu_rt->from, NULL));
+ fib6_info_release(from);
+ }
+
+@@ -1447,7 +1450,6 @@ static DEFINE_SPINLOCK(rt6_exception_lock);
+ static void rt6_remove_exception(struct rt6_exception_bucket *bucket,
+ struct rt6_exception *rt6_ex)
+ {
+- struct fib6_info *from;
+ struct net *net;
+
+ if (!bucket || !rt6_ex)
+@@ -1459,8 +1461,6 @@ static void rt6_remove_exception(struct rt6_exception_bucket *bucket,
+ /* purge completely the exception to allow releasing the held resources:
+ * some [sk] cache may keep the dst around for unlimited time
+ */
+- from = xchg((__force struct fib6_info **)&rt6_ex->rt6i->from, NULL);
+- fib6_info_release(from);
+ dst_dev_put(&rt6_ex->rt6i->dst);
+
+ hlist_del_rcu(&rt6_ex->hlist);
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 815b1df0b2d194..0f660b1d3bd51c 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1238,7 +1238,9 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
+ return -EOPNOTSUPP;
+
+ /* receive/dequeue next skb:
+- * the function understands MSG_PEEK and, thus, does not dequeue skb */
++ * the function understands MSG_PEEK and, thus, does not dequeue skb
++ * only refcount is increased.
++ */
+ skb = skb_recv_datagram(sk, flags, &err);
+ if (!skb) {
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+@@ -1254,9 +1256,8 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
+
+ cskb = skb;
+ if (skb_copy_datagram_msg(cskb, offset, msg, copied)) {
+- if (!(flags & MSG_PEEK))
+- skb_queue_head(&sk->sk_receive_queue, skb);
+- return -EFAULT;
++ err = -EFAULT;
++ goto err_out;
+ }
+
+ /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
+@@ -1273,11 +1274,8 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
+ err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
+ sizeof(IUCV_SKB_CB(skb)->class),
+ (void *)&IUCV_SKB_CB(skb)->class);
+- if (err) {
+- if (!(flags & MSG_PEEK))
+- skb_queue_head(&sk->sk_receive_queue, skb);
+- return err;
+- }
++ if (err)
++ goto err_out;
+
+ /* Mark read part of skb as used */
+ if (!(flags & MSG_PEEK)) {
+@@ -1333,8 +1331,18 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
+ /* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
+ if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC))
+ copied = rlen;
++ if (flags & MSG_PEEK)
++ skb_unref(skb);
+
+ return copied;
++
++err_out:
++ if (!(flags & MSG_PEEK))
++ skb_queue_head(&sk->sk_receive_queue, skb);
++ else
++ skb_unref(skb);
++
++ return err;
+ }
+
+ static inline __poll_t iucv_accept_poll(struct sock *parent)
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
+index fde1140d899efc..cc25fec44f8502 100644
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -1099,7 +1099,7 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
+ lock_sock(sk);
+ if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
+ goto out;
+- rc = copy_from_sockptr(&opt, optval, sizeof(opt));
++ rc = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
+ if (rc)
+ goto out;
+ rc = -EINVAL;
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index 71d60f57a886ce..d1046f495e63ff 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -145,6 +145,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
+ }
+
+ power = ieee80211_chandef_max_power(&chandef);
++ if (local->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
++ power = min(local->user_power_level, power);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index b8357d7c6b3a10..01f6ce970918c5 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2691,8 +2691,8 @@ void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout)
+ if (!fail_tout && !inet_csk(sk)->icsk_mtup.probe_timestamp)
+ return;
+
+- close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies +
+- TCP_TIMEWAIT_LEN;
++ close_timeout = (unsigned long)inet_csk(sk)->icsk_mtup.probe_timestamp -
++ tcp_jiffies32 + jiffies + TCP_TIMEWAIT_LEN;
+
+ /* the close timeout takes precedence on the fail one, and here at least one of
+ * them is active
+diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
+index e4fa00abde6a2a..5988b9bb9029dc 100644
+--- a/net/netfilter/ipset/ip_set_bitmap_ip.c
++++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
+@@ -163,11 +163,8 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
+ if (ret)
+ return ret;
+- if (ip > ip_to) {
++ if (ip > ip_to)
+ swap(ip, ip_to);
+- if (ip < map->first_ip)
+- return -IPSET_ERR_BITMAP_RANGE;
+- }
+ } else if (tb[IPSET_ATTR_CIDR]) {
+ u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
+
+@@ -178,7 +175,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
+ ip_to = ip;
+ }
+
+- if (ip_to > map->last_ip)
++ if (ip < map->first_ip || ip_to > map->last_ip)
+ return -IPSET_ERR_BITMAP_RANGE;
+
+ for (; !before(ip_to, ip); ip += map->hosts) {
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 8a583e8f3c136a..eee7997048fb97 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3231,25 +3231,37 @@ int nft_expr_inner_parse(const struct nft_ctx *ctx, const struct nlattr *nla,
+ if (!tb[NFTA_EXPR_DATA] || !tb[NFTA_EXPR_NAME])
+ return -EINVAL;
+
++ rcu_read_lock();
++
+ type = __nft_expr_type_get(ctx->family, tb[NFTA_EXPR_NAME]);
+- if (!type)
+- return -ENOENT;
++ if (!type) {
++ err = -ENOENT;
++ goto out_unlock;
++ }
+
+- if (!type->inner_ops)
+- return -EOPNOTSUPP;
++ if (!type->inner_ops) {
++ err = -EOPNOTSUPP;
++ goto out_unlock;
++ }
+
+ err = nla_parse_nested_deprecated(info->tb, type->maxattr,
+ tb[NFTA_EXPR_DATA],
+ type->policy, NULL);
+ if (err < 0)
+- goto err_nla_parse;
++ goto out_unlock;
+
+ info->attr = nla;
+ info->ops = type->inner_ops;
+
++ /* No module reference will be taken on type->owner.
++ * Presence of type->inner_ops implies that the expression
++ * is builtin, so it cannot go away.
++ */
++ rcu_read_unlock();
+ return 0;
+
+-err_nla_parse:
++out_unlock:
++ rcu_read_unlock();
+ return err;
+ }
+
+@@ -3349,13 +3361,15 @@ void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
+ * Rules
+ */
+
+-static struct nft_rule *__nft_rule_lookup(const struct nft_chain *chain,
++static struct nft_rule *__nft_rule_lookup(const struct net *net,
++ const struct nft_chain *chain,
+ u64 handle)
+ {
+ struct nft_rule *rule;
+
+ // FIXME: this sucks
+- list_for_each_entry_rcu(rule, &chain->rules, list) {
++ list_for_each_entry_rcu(rule, &chain->rules, list,
++ lockdep_commit_lock_is_held(net)) {
+ if (handle == rule->handle)
+ return rule;
+ }
+@@ -3363,13 +3377,14 @@ static struct nft_rule *__nft_rule_lookup(const struct nft_chain *chain,
+ return ERR_PTR(-ENOENT);
+ }
+
+-static struct nft_rule *nft_rule_lookup(const struct nft_chain *chain,
++static struct nft_rule *nft_rule_lookup(const struct net *net,
++ const struct nft_chain *chain,
+ const struct nlattr *nla)
+ {
+ if (nla == NULL)
+ return ERR_PTR(-EINVAL);
+
+- return __nft_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
++ return __nft_rule_lookup(net, chain, be64_to_cpu(nla_get_be64(nla)));
+ }
+
+ static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
+@@ -3661,9 +3676,10 @@ static int nf_tables_dump_rules_done(struct netlink_callback *cb)
+ return 0;
+ }
+
+-/* called with rcu_read_lock held */
+-static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+- const struct nlattr * const nla[])
++/* Caller must hold rcu read lock or transaction mutex */
++static struct sk_buff *
++nf_tables_getrule_single(u32 portid, const struct nfnl_info *info,
++ const struct nlattr * const nla[], bool reset)
+ {
+ struct netlink_ext_ack *extack = info->extack;
+ u8 genmask = nft_genmask_cur(info->net);
+@@ -3673,60 +3689,82 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+ struct net *net = info->net;
+ struct nft_table *table;
+ struct sk_buff *skb2;
+- bool reset = false;
+ int err;
+
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start= nf_tables_dump_rules_start,
+- .dump = nf_tables_dump_rules,
+- .done = nf_tables_dump_rules_done,
+- .module = THIS_MODULE,
+- .data = (void *)nla,
+- };
+-
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+ table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask, 0);
+ if (IS_ERR(table)) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_TABLE]);
+- return PTR_ERR(table);
++ return ERR_CAST(table);
+ }
+
+ chain = nft_chain_lookup(net, table, nla[NFTA_RULE_CHAIN], genmask);
+ if (IS_ERR(chain)) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
+- return PTR_ERR(chain);
++ return ERR_CAST(chain);
+ }
+
+- rule = nft_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
++ rule = nft_rule_lookup(net, chain, nla[NFTA_RULE_HANDLE]);
+ if (IS_ERR(rule)) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
+- return PTR_ERR(rule);
++ return ERR_CAST(rule);
+ }
+
+ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
+ if (!skb2)
+- return -ENOMEM;
++ return ERR_PTR(-ENOMEM);
++
++ err = nf_tables_fill_rule_info(skb2, net, portid,
++ info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
++ family, table, chain, rule, 0, reset);
++ if (err < 0) {
++ kfree_skb(skb2);
++ return ERR_PTR(err);
++ }
++
++ return skb2;
++}
++
++static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
++ const struct nlattr * const nla[])
++{
++ struct nftables_pernet *nft_net = nft_pernet(info->net);
++ u32 portid = NETLINK_CB(skb).portid;
++ struct net *net = info->net;
++ struct sk_buff *skb2;
++ bool reset = false;
++ char *buf;
++
++ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
++ struct netlink_dump_control c = {
++ .start= nf_tables_dump_rules_start,
++ .dump = nf_tables_dump_rules,
++ .done = nf_tables_dump_rules_done,
++ .module = THIS_MODULE,
++ .data = (void *)nla,
++ };
++
++ return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
++ }
+
+ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
+ reset = true;
+
+- err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
+- info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
+- family, table, chain, rule, 0, reset);
+- if (err < 0)
+- goto err_fill_rule_info;
++ skb2 = nf_tables_getrule_single(portid, info, nla, reset);
++ if (IS_ERR(skb2))
++ return PTR_ERR(skb2);
+
+- if (reset)
+- audit_log_rule_reset(table, nft_pernet(net)->base_seq, 1);
++ if (!reset)
++ return nfnetlink_unicast(skb2, net, portid);
+
+- return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
++ buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
++ nla_len(nla[NFTA_RULE_TABLE]),
++ (char *)nla_data(nla[NFTA_RULE_TABLE]),
++ nft_net->base_seq);
++ audit_log_nfcfg(buf, info->nfmsg->nfgen_family, 1,
++ AUDIT_NFT_OP_RULE_RESET, GFP_ATOMIC);
++ kfree(buf);
+
+-err_fill_rule_info:
+- kfree_skb(skb2);
+- return err;
++ return nfnetlink_unicast(skb2, net, portid);
+ }
+
+ void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule)
+@@ -3938,7 +3976,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+
+ if (nla[NFTA_RULE_HANDLE]) {
+ handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
+- rule = __nft_rule_lookup(chain, handle);
++ rule = __nft_rule_lookup(net, chain, handle);
+ if (IS_ERR(rule)) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
+ return PTR_ERR(rule);
+@@ -3960,7 +3998,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+
+ if (nla[NFTA_RULE_POSITION]) {
+ pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
+- old_rule = __nft_rule_lookup(chain, pos_handle);
++ old_rule = __nft_rule_lookup(net, chain, pos_handle);
+ if (IS_ERR(old_rule)) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_POSITION]);
+ return PTR_ERR(old_rule);
+@@ -4177,7 +4215,7 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info,
+
+ if (chain) {
+ if (nla[NFTA_RULE_HANDLE]) {
+- rule = nft_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
++ rule = nft_rule_lookup(info->net, chain, nla[NFTA_RULE_HANDLE]);
+ if (IS_ERR(rule)) {
+ if (PTR_ERR(rule) == -ENOENT &&
+ NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_DESTROYRULE)
+@@ -7577,9 +7615,7 @@ static int nf_tables_updobj(const struct nft_ctx *ctx,
+ struct nft_trans *trans;
+ int err = -ENOMEM;
+
+- if (!try_module_get(type->owner))
+- return -ENOENT;
+-
++ /* caller must have obtained type->owner reference. */
+ trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ,
+ sizeof(struct nft_trans_obj));
+ if (!trans)
+@@ -7647,12 +7683,16 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info,
+ if (info->nlh->nlmsg_flags & NLM_F_REPLACE)
+ return -EOPNOTSUPP;
+
+- type = __nft_obj_type_get(objtype, family);
+- if (WARN_ON_ONCE(!type))
+- return -ENOENT;
++ if (!obj->ops->update)
++ return 0;
++
++ type = nft_obj_type_get(net, objtype, family);
++ if (WARN_ON_ONCE(IS_ERR(type)))
++ return PTR_ERR(type);
+
+ nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla);
+
++ /* type->owner reference is put when transaction object is released. */
+ return nf_tables_updobj(&ctx, type, nla[NFTA_OBJ_DATA], obj);
+ }
+
+@@ -7888,7 +7928,7 @@ static int nf_tables_dump_obj_done(struct netlink_callback *cb)
+ return 0;
+ }
+
+-/* called with rcu_read_lock held */
++/* Caller must hold rcu read lock or transaction mutex */
+ static struct sk_buff *
+ nf_tables_getobj_single(u32 portid, const struct nfnl_info *info,
+ const struct nlattr * const nla[], bool reset)
+@@ -9394,9 +9434,10 @@ static void nft_obj_commit_update(struct nft_trans *trans)
+ obj = nft_trans_obj(trans);
+ newobj = nft_trans_obj_newobj(trans);
+
+- if (obj->ops->update)
+- obj->ops->update(obj, newobj);
++ if (WARN_ON_ONCE(!obj->ops->update))
++ return;
+
++ obj->ops->update(obj, newobj);
+ nft_obj_destroy(&trans->ctx, newobj);
+ }
+
+diff --git a/net/netlink/diag.c b/net/netlink/diag.c
+index 9c4f231be27572..7b15aa5f7bc20b 100644
+--- a/net/netlink/diag.c
++++ b/net/netlink/diag.c
+@@ -241,6 +241,7 @@ static int netlink_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
+ }
+
+ static const struct sock_diag_handler netlink_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_NETLINK,
+ .dump = netlink_diag_handler_dump,
+ };
+diff --git a/net/packet/diag.c b/net/packet/diag.c
+index f6b200cb3c0668..d4142636aa2b71 100644
+--- a/net/packet/diag.c
++++ b/net/packet/diag.c
+@@ -245,6 +245,7 @@ static int packet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
+ }
+
+ static const struct sock_diag_handler packet_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_PACKET,
+ .dump = packet_diag_handler_dump,
+ };
+diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
+index 4e32d659524e0d..b12edbe0ef45c1 100644
+--- a/net/rfkill/rfkill-gpio.c
++++ b/net/rfkill/rfkill-gpio.c
+@@ -31,8 +31,12 @@ static int rfkill_gpio_set_power(void *data, bool blocked)
+ {
+ struct rfkill_gpio_data *rfkill = data;
+
+- if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled)
+- clk_enable(rfkill->clk);
++ if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled) {
++ int ret = clk_enable(rfkill->clk);
++
++ if (ret)
++ return ret;
++ }
+
+ gpiod_set_value_cansleep(rfkill->shutdown_gpio, !blocked);
+ gpiod_set_value_cansleep(rfkill->reset_gpio, !blocked);
+diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
+index fa8aec78f63d70..205e0d4d048ea2 100644
+--- a/net/rxrpc/af_rxrpc.c
++++ b/net/rxrpc/af_rxrpc.c
+@@ -661,9 +661,10 @@ static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
+ ret = -EISCONN;
+ if (rx->sk.sk_state != RXRPC_UNBOUND)
+ goto error;
+- ret = copy_from_sockptr(&min_sec_level, optval,
+- sizeof(unsigned int));
+- if (ret < 0)
++ ret = copy_safe_from_sockptr(&min_sec_level,
++ sizeof(min_sec_level),
++ optval, optlen);
++ if (ret)
+ goto error;
+ ret = -EINVAL;
+ if (min_sec_level > RXRPC_SECURITY_MAX)
+diff --git a/net/sched/act_api.c b/net/sched/act_api.c
+index 4572aa6e0273f8..e509ac28c49299 100644
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -62,7 +62,7 @@ static void tcf_set_action_cookie(struct tc_cookie __rcu **old_cookie,
+ {
+ struct tc_cookie *old;
+
+- old = xchg((__force struct tc_cookie **)old_cookie, new_cookie);
++ old = unrcu_pointer(xchg(old_cookie, RCU_INITIALIZER(new_cookie)));
+ if (old)
+ call_rcu(&old->rcu, tcf_free_cookie_rcu);
+ }
+diff --git a/net/smc/smc_diag.c b/net/smc/smc_diag.c
+index 37833b96b508ef..d58c699b5328ae 100644
+--- a/net/smc/smc_diag.c
++++ b/net/smc/smc_diag.c
+@@ -250,6 +250,7 @@ static int smc_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
+ }
+
+ static const struct sock_diag_handler smc_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_SMC,
+ .dump = smc_diag_handler_dump,
+ };
+diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
+index 95ff747061046c..3298da2e37e43d 100644
+--- a/net/sunrpc/cache.c
++++ b/net/sunrpc/cache.c
+@@ -1431,7 +1431,9 @@ static int c_show(struct seq_file *m, void *p)
+ seq_printf(m, "# expiry=%lld refcnt=%d flags=%lx\n",
+ convert_to_wallclock(cp->expiry_time),
+ kref_read(&cp->ref), cp->flags);
+- cache_get(cp);
++ if (!cache_get_rcu(cp))
++ return 0;
++
+ if (cache_check(cd, cp, NULL))
+ /* cache_check does a cache_put on failure */
+ seq_puts(m, "# ");
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index 933e12e3a55c75..83996eea100626 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -1562,6 +1562,10 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
+ newlen = error;
+
+ if (protocol == IPPROTO_TCP) {
++ __netns_tracker_free(net, &sock->sk->ns_tracker, false);
++ sock->sk->sk_net_refcnt = 1;
++ get_net_track(net, &sock->sk->ns_tracker, GFP_KERNEL);
++ sock_inuse_add(net, 1);
+ if ((error = kernel_listen(sock, 64)) < 0)
+ goto bummer;
+ }
+diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
+index f0d5eeed4c886f..e1d4e426b21fa9 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma.c
++++ b/net/sunrpc/xprtrdma/svc_rdma.c
+@@ -234,25 +234,34 @@ static int svc_rdma_proc_init(void)
+
+ rc = percpu_counter_init(&svcrdma_stat_read, 0, GFP_KERNEL);
+ if (rc)
+- goto out_err;
++ goto err;
+ rc = percpu_counter_init(&svcrdma_stat_recv, 0, GFP_KERNEL);
+ if (rc)
+- goto out_err;
++ goto err_read;
+ rc = percpu_counter_init(&svcrdma_stat_sq_starve, 0, GFP_KERNEL);
+ if (rc)
+- goto out_err;
++ goto err_recv;
+ rc = percpu_counter_init(&svcrdma_stat_write, 0, GFP_KERNEL);
+ if (rc)
+- goto out_err;
++ goto err_sq;
+
+ svcrdma_table_header = register_sysctl("sunrpc/svc_rdma",
+ svcrdma_parm_table);
++ if (!svcrdma_table_header)
++ goto err_write;
++
+ return 0;
+
+-out_err:
++err_write:
++ rc = -ENOMEM;
++ percpu_counter_destroy(&svcrdma_stat_write);
++err_sq:
+ percpu_counter_destroy(&svcrdma_stat_sq_starve);
++err_recv:
+ percpu_counter_destroy(&svcrdma_stat_recv);
++err_read:
+ percpu_counter_destroy(&svcrdma_stat_read);
++err:
+ return rc;
+ }
+
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+index 3b05f90a3e50dd..9cec7bcb8a9768 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+@@ -478,7 +478,13 @@ static bool xdr_check_write_chunk(struct svc_rdma_recv_ctxt *rctxt)
+ if (xdr_stream_decode_u32(&rctxt->rc_stream, &segcount))
+ return false;
+
+- /* A bogus segcount causes this buffer overflow check to fail. */
++ /* Before trusting the segcount value enough to use it in
++ * a computation, perform a simple range check. This is an
++ * arbitrary but sensible limit (ie, not architectural).
++ */
++ if (unlikely(segcount > RPCSVC_MAXPAGES))
++ return false;
++
+ p = xdr_inline_decode(&rctxt->rc_stream,
+ segcount * rpcrdma_segment_maxsz * sizeof(*p));
+ return p != NULL;
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index 50490b1e8a0d09..1c4bc8234ea875 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -1186,6 +1186,7 @@ static void xs_sock_reset_state_flags(struct rpc_xprt *xprt)
+ clear_bit(XPRT_SOCK_WAKE_WRITE, &transport->sock_state);
+ clear_bit(XPRT_SOCK_WAKE_DISCONNECT, &transport->sock_state);
+ clear_bit(XPRT_SOCK_NOSPACE, &transport->sock_state);
++ clear_bit(XPRT_SOCK_UPD_TIMEOUT, &transport->sock_state);
+ }
+
+ static void xs_run_error_worker(struct sock_xprt *transport, unsigned int nr)
+@@ -1920,6 +1921,13 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt,
+ goto out;
+ }
+
++ if (protocol == IPPROTO_TCP) {
++ __netns_tracker_free(xprt->xprt_net, &sock->sk->ns_tracker, false);
++ sock->sk->sk_net_refcnt = 1;
++ get_net_track(xprt->xprt_net, &sock->sk->ns_tracker, GFP_KERNEL);
++ sock_inuse_add(xprt->xprt_net, 1);
++ }
++
+ filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
+ if (IS_ERR(filp))
+ return ERR_CAST(filp);
+@@ -2595,11 +2603,10 @@ static int xs_tls_handshake_sync(struct rpc_xprt *lower_xprt, struct xprtsec_par
+ rc = wait_for_completion_interruptible_timeout(&lower_transport->handshake_done,
+ XS_TLS_HANDSHAKE_TO);
+ if (rc <= 0) {
+- if (!tls_handshake_cancel(sk)) {
+- if (rc == 0)
+- rc = -ETIMEDOUT;
+- goto out_put_xprt;
+- }
++ tls_handshake_cancel(sk);
++ if (rc == 0)
++ rc = -ETIMEDOUT;
++ goto out_put_xprt;
+ }
+
+ rc = lower_transport->xprt_err;
+diff --git a/net/tipc/diag.c b/net/tipc/diag.c
+index 73137f4aeb68f9..11da9d2ebbf699 100644
+--- a/net/tipc/diag.c
++++ b/net/tipc/diag.c
+@@ -95,6 +95,7 @@ static int tipc_sock_diag_handler_dump(struct sk_buff *skb,
+ }
+
+ static const struct sock_diag_handler tipc_sock_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_TIPC,
+ .dump = tipc_sock_diag_handler_dump,
+ };
+diff --git a/net/unix/diag.c b/net/unix/diag.c
+index 1de7500b41b616..a6bd861314df08 100644
+--- a/net/unix/diag.c
++++ b/net/unix/diag.c
+@@ -322,6 +322,7 @@ static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
+ }
+
+ static const struct sock_diag_handler unix_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_UNIX,
+ .dump = unix_diag_handler_dump,
+ };
+diff --git a/net/vmw_vsock/diag.c b/net/vmw_vsock/diag.c
+index a2823b1c5e28b1..6efa9eb93336f2 100644
+--- a/net/vmw_vsock/diag.c
++++ b/net/vmw_vsock/diag.c
+@@ -157,6 +157,7 @@ static int vsock_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
+ }
+
+ static const struct sock_diag_handler vsock_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_VSOCK,
+ .dump = vsock_diag_handler_dump,
+ };
+diff --git a/net/xdp/xsk_diag.c b/net/xdp/xsk_diag.c
+index 22b36c8143cfd5..e1012bfec72079 100644
+--- a/net/xdp/xsk_diag.c
++++ b/net/xdp/xsk_diag.c
+@@ -194,6 +194,7 @@ static int xsk_diag_handler_dump(struct sk_buff *nlskb, struct nlmsghdr *hdr)
+ }
+
+ static const struct sock_diag_handler xsk_diag_handler = {
++ .owner = THIS_MODULE,
+ .family = AF_XDP,
+ .dump = xsk_diag_handler_dump,
+ };
+diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
+index 34ae73f5db068a..7bdb3a5a18a064 100644
+--- a/rust/macros/lib.rs
++++ b/rust/macros/lib.rs
+@@ -298,7 +298,7 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
+ /// macro_rules! pub_no_prefix {
+ /// ($prefix:ident, $($newname:ident),+) => {
+ /// kernel::macros::paste! {
+-/// $(pub(crate) const fn [<$newname:lower:span>]: u32 = [<$prefix $newname:span>];)+
++/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+
+ /// }
+ /// };
+ /// }
+diff --git a/samples/bpf/xdp_adjust_tail_kern.c b/samples/bpf/xdp_adjust_tail_kern.c
+index ffdd548627f0a4..da67bcad1c6381 100644
+--- a/samples/bpf/xdp_adjust_tail_kern.c
++++ b/samples/bpf/xdp_adjust_tail_kern.c
+@@ -57,6 +57,7 @@ static __always_inline void swap_mac(void *data, struct ethhdr *orig_eth)
+
+ static __always_inline __u16 csum_fold_helper(__u32 csum)
+ {
++ csum = (csum & 0xffff) + (csum >> 16);
+ return ~((csum & 0xffff) + (csum >> 16));
+ }
+
+diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
+index 7d16f863edf1c7..6744b58c35083f 100755
+--- a/scripts/checkpatch.pl
++++ b/scripts/checkpatch.pl
+@@ -28,6 +28,7 @@ my %verbose_messages = ();
+ my %verbose_emitted = ();
+ my $tree = 1;
+ my $chk_signoff = 1;
++my $chk_fixes_tag = 1;
+ my $chk_patch = 1;
+ my $tst_only;
+ my $emacs = 0;
+@@ -88,6 +89,7 @@ Options:
+ -v, --verbose verbose mode
+ --no-tree run without a kernel tree
+ --no-signoff do not check for 'Signed-off-by' line
++ --no-fixes-tag do not check for 'Fixes:' tag
+ --patch treat FILE as patchfile (default)
+ --emacs emacs compile window format
+ --terse one line per report
+@@ -295,6 +297,7 @@ GetOptions(
+ 'v|verbose!' => \$verbose,
+ 'tree!' => \$tree,
+ 'signoff!' => \$chk_signoff,
++ 'fixes-tag!' => \$chk_fixes_tag,
+ 'patch!' => \$chk_patch,
+ 'emacs!' => \$emacs,
+ 'terse!' => \$terse,
+@@ -1256,6 +1259,7 @@ sub git_commit_info {
+ }
+
+ $chk_signoff = 0 if ($file);
++$chk_fixes_tag = 0 if ($file);
+
+ my @rawlines = ();
+ my @lines = ();
+@@ -2635,6 +2639,9 @@ sub process {
+
+ our $clean = 1;
+ my $signoff = 0;
++ my $fixes_tag = 0;
++ my $is_revert = 0;
++ my $needs_fixes_tag = "";
+ my $author = '';
+ my $authorsignoff = 0;
+ my $author_sob = '';
+@@ -3188,38 +3195,44 @@ sub process {
+ }
+ }
+
++# These indicate a bug fix
++ if (!$in_header_lines && !$is_patch &&
++ $line =~ /^This reverts commit/) {
++ $is_revert = 1;
++ }
++
++ if (!$in_header_lines && !$is_patch &&
++ $line =~ /((?:(?:BUG: K.|UB)SAN: |Call Trace:|stable\@|syzkaller))/) {
++ $needs_fixes_tag = $1;
++ }
+
+ # Check Fixes: styles is correct
+ if (!$in_header_lines &&
+- $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
+- my $orig_commit = "";
+- my $id = "0123456789ab";
+- my $title = "commit title";
+- my $tag_case = 1;
+- my $tag_space = 1;
+- my $id_length = 1;
+- my $id_case = 1;
++ $line =~ /^\s*(fixes:?)\s*(?:commit\s*)?([0-9a-f]{5,40})(?:\s*($balanced_parens))?/i) {
++ my $tag = $1;
++ my $orig_commit = $2;
++ my $title;
+ my $title_has_quotes = 0;
+-
+- if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) {
+- my $tag = $1;
+- $orig_commit = $2;
+- $title = $3;
+-
+- $tag_case = 0 if $tag eq "Fixes:";
+- $tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i);
+-
+- $id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i);
+- $id_case = 0 if ($orig_commit !~ /[A-F]/);
+-
++ $fixes_tag = 1;
++ if (defined $3) {
+ # Always strip leading/trailing parens then double quotes if existing
+- $title = substr($title, 1, -1);
++ $title = substr($3, 1, -1);
+ if ($title =~ /^".*"$/) {
+ $title = substr($title, 1, -1);
+ $title_has_quotes = 1;
+ }
++ } else {
++ $title = "commit title"
+ }
+
++
++ my $tag_case = not ($tag eq "Fixes:");
++ my $tag_space = not ($line =~ /^fixes:? [0-9a-f]{5,40} ($balanced_parens)/i);
++
++ my $id_length = not ($orig_commit =~ /^[0-9a-f]{12}$/i);
++ my $id_case = not ($orig_commit !~ /[A-F]/);
++
++ my $id = "0123456789ab";
+ my ($cid, $ctitle) = git_commit_info($orig_commit, $id,
+ $title);
+
+@@ -7680,6 +7693,12 @@ sub process {
+ ERROR("NOT_UNIFIED_DIFF",
+ "Does not appear to be a unified-diff format patch\n");
+ }
++ if ($is_patch && $has_commit_log && $chk_fixes_tag) {
++ if ($needs_fixes_tag ne "" && !$is_revert && !$fixes_tag) {
++ WARN("MISSING_FIXES_TAG",
++ "The commit message has '$needs_fixes_tag', perhaps it also needs a 'Fixes:' tag?\n");
++ }
++ }
+ if ($is_patch && $has_commit_log && $chk_signoff) {
+ if ($signoff == 0) {
+ ERROR("MISSING_SIGN_OFF",
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index 6583b36dbe6948..efbb4836ec668f 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -809,10 +809,7 @@ static int do_eisa_entry(const char *filename, void *symval,
+ char *alias)
+ {
+ DEF_FIELD_ADDR(symval, eisa_device_id, sig);
+- if (sig[0])
+- sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig);
+- else
+- strcat(alias, "*");
++ sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig);
+ return 1;
+ }
+
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index 828d5cc367169f..4110d559ed6881 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -792,25 +792,15 @@ static void check_section(const char *modname, struct elf_info *elf,
+
+
+ #define ALL_INIT_DATA_SECTIONS \
+- ".init.setup", ".init.rodata", ".meminit.rodata", \
+- ".init.data", ".meminit.data"
+-#define ALL_EXIT_DATA_SECTIONS \
+- ".exit.data", ".memexit.data"
+-
+-#define ALL_INIT_TEXT_SECTIONS \
+- ".init.text", ".meminit.text"
+-#define ALL_EXIT_TEXT_SECTIONS \
+- ".exit.text"
++ ".init.setup", ".init.rodata", ".init.data"
+
+ #define ALL_PCI_INIT_SECTIONS \
+ ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \
+ ".pci_fixup_enable", ".pci_fixup_resume", \
+ ".pci_fixup_resume_early", ".pci_fixup_suspend"
+
+-#define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
+-
+-#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
+-#define ALL_EXIT_SECTIONS EXIT_SECTIONS
++#define ALL_INIT_SECTIONS ".init.*"
++#define ALL_EXIT_SECTIONS ".exit.*"
+
+ #define DATA_SECTIONS ".data", ".data.rel"
+ #define TEXT_SECTIONS ".text", ".text.*", ".sched.text", \
+@@ -820,12 +810,7 @@ static void check_section(const char *modname, struct elf_info *elf,
+ ".fixup", ".entry.text", ".exception.text", \
+ ".coldtext", ".softirqentry.text"
+
+-#define INIT_SECTIONS ".init.*"
+-#define MEM_INIT_SECTIONS ".meminit.*"
+-
+-#define EXIT_SECTIONS ".exit.*"
+-
+-#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
++#define ALL_TEXT_SECTIONS ".init.text", ".exit.text", \
+ TEXT_SECTIONS, OTHER_TEXT_SECTIONS
+
+ enum mismatch {
+@@ -869,7 +854,7 @@ static const struct sectioncheck sectioncheck[] = {
+ },
+ {
+ .fromsec = { DATA_SECTIONS, NULL },
+- .bad_tosec = { ALL_XXXINIT_SECTIONS, INIT_SECTIONS, NULL },
++ .bad_tosec = { ALL_INIT_SECTIONS, NULL },
+ .mismatch = DATA_TO_ANY_INIT,
+ },
+ {
+@@ -877,12 +862,6 @@ static const struct sectioncheck sectioncheck[] = {
+ .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
+ .mismatch = TEXTDATA_TO_ANY_EXIT,
+ },
+-/* Do not reference init code/data from meminit code/data */
+-{
+- .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
+- .bad_tosec = { INIT_SECTIONS, NULL },
+- .mismatch = XXXINIT_TO_SOME_INIT,
+-},
+ /* Do not use exit code/data from init code */
+ {
+ .fromsec = { ALL_INIT_SECTIONS, NULL },
+@@ -897,7 +876,7 @@ static const struct sectioncheck sectioncheck[] = {
+ },
+ {
+ .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
+- .bad_tosec = { INIT_SECTIONS, NULL },
++ .bad_tosec = { ALL_INIT_SECTIONS, NULL },
+ .mismatch = ANY_INIT_TO_ANY_EXIT,
+ },
+ {
+@@ -1009,12 +988,6 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
+ "*_console")))
+ return 0;
+
+- /* symbols in data sections that may refer to meminit sections */
+- if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
+- match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS)) &&
+- match(fromsym, PATTERNS("*driver")))
+- return 0;
+-
+ /*
+ * symbols in data sections must not refer to .exit.*, but there are
+ * quite a few offenders, so hide these unless for W=1 builds until
+@@ -1022,7 +995,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
+ */
+ if (!extra_warn &&
+ match(fromsec, PATTERNS(DATA_SECTIONS)) &&
+- match(tosec, PATTERNS(EXIT_SECTIONS)) &&
++ match(tosec, PATTERNS(ALL_EXIT_SECTIONS)) &&
+ match(fromsym, PATTERNS("*driver")))
+ return 0;
+
+@@ -1187,10 +1160,10 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf,
+ ELF_ST_TYPE(sym->st_info) == STT_LOPROC)
+ s->is_func = true;
+
+- if (match(secname, PATTERNS(INIT_SECTIONS)))
++ if (match(secname, PATTERNS(ALL_INIT_SECTIONS)))
+ warn("%s: %s: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.\n",
+ mod->name, name);
+- else if (match(secname, PATTERNS(EXIT_SECTIONS)))
++ else if (match(secname, PATTERNS(ALL_EXIT_SECTIONS)))
+ warn("%s: %s: EXPORT_SYMBOL used for exit symbol. Remove __exit or EXPORT_SYMBOL.\n",
+ mod->name, name);
+ }
+diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
+index 2fb6a2ea0b998c..82485972006238 100644
+--- a/security/apparmor/capability.c
++++ b/security/apparmor/capability.c
+@@ -96,6 +96,8 @@ static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile
+ return error;
+ } else {
+ aa_put_profile(ent->profile);
++ if (profile != ent->profile)
++ cap_clear(ent->caps);
+ ent->profile = aa_get_profile(profile);
+ cap_raise(ent->caps, cap);
+ }
+diff --git a/security/apparmor/policy_unpack_test.c b/security/apparmor/policy_unpack_test.c
+index 2b8003eb4f463a..dd551587fe4ac7 100644
+--- a/security/apparmor/policy_unpack_test.c
++++ b/security/apparmor/policy_unpack_test.c
+@@ -281,6 +281,8 @@ static void policy_unpack_test_unpack_strdup_with_null_name(struct kunit *test)
+ ((uintptr_t)puf->e->start <= (uintptr_t)string)
+ && ((uintptr_t)string <= (uintptr_t)puf->e->end));
+ KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
++
++ kfree(string);
+ }
+
+ static void policy_unpack_test_unpack_strdup_with_name(struct kunit *test)
+@@ -296,6 +298,8 @@ static void policy_unpack_test_unpack_strdup_with_name(struct kunit *test)
+ ((uintptr_t)puf->e->start <= (uintptr_t)string)
+ && ((uintptr_t)string <= (uintptr_t)puf->e->end));
+ KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
++
++ kfree(string);
+ }
+
+ static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test)
+@@ -313,6 +317,8 @@ static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test)
+ KUNIT_EXPECT_EQ(test, size, 0);
+ KUNIT_EXPECT_NULL(test, string);
+ KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start);
++
++ kfree(string);
+ }
+
+ static void policy_unpack_test_unpack_nameX_with_null_name(struct kunit *test)
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index cc21c483c4a579..e40de64ec85cb5 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -3794,9 +3794,11 @@ static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf)
+ return VM_FAULT_SIGBUS;
+ if (substream->ops->page)
+ page = substream->ops->page(substream, offset);
+- else if (!snd_pcm_get_dma_buf(substream))
++ else if (!snd_pcm_get_dma_buf(substream)) {
++ if (WARN_ON_ONCE(!runtime->dma_area))
++ return VM_FAULT_SIGBUS;
+ page = virt_to_page(runtime->dma_area + offset);
+- else
++ } else
+ page = snd_sgbuf_get_page(snd_pcm_get_dma_buf(substream), offset);
+ if (!page)
+ return VM_FAULT_SIGBUS;
+diff --git a/sound/core/ump.c b/sound/core/ump.c
+index 8a7ecec74b5d61..b1ce4756961a54 100644
+--- a/sound/core/ump.c
++++ b/sound/core/ump.c
+@@ -724,7 +724,10 @@ static void fill_fb_info(struct snd_ump_endpoint *ump,
+ info->ui_hint = buf->fb_info.ui_hint;
+ info->first_group = buf->fb_info.first_group;
+ info->num_groups = buf->fb_info.num_groups;
+- info->flags = buf->fb_info.midi_10;
++ if (buf->fb_info.midi_10 < 2)
++ info->flags = buf->fb_info.midi_10;
++ else
++ info->flags = SNDRV_UMP_BLOCK_IS_MIDI1 | SNDRV_UMP_BLOCK_IS_LOWSPEED;
+ info->active = buf->fb_info.active;
+ info->midi_ci_version = buf->fb_info.midi_ci_version;
+ info->sysex8_streams = buf->fb_info.sysex8_streams;
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index e7c2ef6c6b4cb0..16a3e478e50b94 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -721,6 +721,10 @@ static const struct config_entry acpi_config_table[] = {
+ #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
+ IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+ /* BayTrail */
++ {
++ .flags = FLAG_SST_OR_SOF_BYT,
++ .acpi_hid = "LPE0F28",
++ },
+ {
+ .flags = FLAG_SST_OR_SOF_BYT,
+ .acpi_hid = "80860F28",
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index ffe298eb7b369b..92299bab251572 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -471,6 +471,8 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
+ break;
+ case 0x10ec0234:
+ case 0x10ec0274:
++ alc_write_coef_idx(codec, 0x6e, 0x0c25);
++ fallthrough;
+ case 0x10ec0294:
+ case 0x10ec0700:
+ case 0x10ec0701:
+@@ -3602,25 +3604,22 @@ static void alc256_init(struct hda_codec *codec)
+
+ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+
+- if (hp_pin_sense)
++ if (hp_pin_sense) {
+ msleep(2);
++ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+
+- alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+-
+- snd_hda_codec_write(codec, hp_pin, 0,
+- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+-
+- if (hp_pin_sense || spec->ultra_low_power)
+- msleep(85);
+-
+- snd_hda_codec_write(codec, hp_pin, 0,
++ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+
+- if (hp_pin_sense || spec->ultra_low_power)
+- msleep(100);
++ msleep(75);
++
++ snd_hda_codec_write(codec, hp_pin, 0,
++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+
++ msleep(75);
++ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
++ }
+ alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
+- alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
+ alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
+ alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
+ /*
+@@ -3644,29 +3643,28 @@ static void alc256_shutup(struct hda_codec *codec)
+ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+
+- if (hp_pin_sense)
++ if (hp_pin_sense) {
+ msleep(2);
+
+- snd_hda_codec_write(codec, hp_pin, 0,
++ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+
+- if (hp_pin_sense || spec->ultra_low_power)
+- msleep(85);
++ msleep(75);
+
+ /* 3k pull low control for Headset jack. */
+ /* NOTE: call this before clearing the pin, otherwise codec stalls */
+ /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
+ * when booting with headset plugged. So skip setting it for the codec alc257
+ */
+- if (spec->en_3kpull_low)
+- alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
++ if (spec->en_3kpull_low)
++ alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
+
+- if (!spec->no_shutup_pins)
+- snd_hda_codec_write(codec, hp_pin, 0,
++ if (!spec->no_shutup_pins)
++ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+
+- if (hp_pin_sense || spec->ultra_low_power)
+- msleep(100);
++ msleep(75);
++ }
+
+ alc_auto_setup_eapd(codec, false);
+ alc_shutup_pins(codec);
+@@ -3761,33 +3759,28 @@ static void alc225_init(struct hda_codec *codec)
+ hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+ hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
+
+- if (hp1_pin_sense || hp2_pin_sense)
++ if (hp1_pin_sense || hp2_pin_sense) {
+ msleep(2);
++ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+
+- alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+-
+- if (hp1_pin_sense || spec->ultra_low_power)
+- snd_hda_codec_write(codec, hp_pin, 0,
+- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+- if (hp2_pin_sense)
+- snd_hda_codec_write(codec, 0x16, 0,
+- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+-
+- if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
+- msleep(85);
+-
+- if (hp1_pin_sense || spec->ultra_low_power)
+- snd_hda_codec_write(codec, hp_pin, 0,
+- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+- if (hp2_pin_sense)
+- snd_hda_codec_write(codec, 0x16, 0,
+- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
++ if (hp1_pin_sense)
++ snd_hda_codec_write(codec, hp_pin, 0,
++ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
++ if (hp2_pin_sense)
++ snd_hda_codec_write(codec, 0x16, 0,
++ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
++ msleep(75);
+
+- if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
+- msleep(100);
++ if (hp1_pin_sense)
++ snd_hda_codec_write(codec, hp_pin, 0,
++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
++ if (hp2_pin_sense)
++ snd_hda_codec_write(codec, 0x16, 0,
++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+
+- alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
+- alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
++ msleep(75);
++ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
++ }
+ }
+
+ static void alc225_shutup(struct hda_codec *codec)
+@@ -3799,36 +3792,35 @@ static void alc225_shutup(struct hda_codec *codec)
+ if (!hp_pin)
+ hp_pin = 0x21;
+
+- alc_disable_headset_jack_key(codec);
+- /* 3k pull low control for Headset jack. */
+- alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
+-
+ hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+ hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
+
+- if (hp1_pin_sense || hp2_pin_sense)
++ if (hp1_pin_sense || hp2_pin_sense) {
++ alc_disable_headset_jack_key(codec);
++ /* 3k pull low control for Headset jack. */
++ alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
+ msleep(2);
+
+- if (hp1_pin_sense || spec->ultra_low_power)
+- snd_hda_codec_write(codec, hp_pin, 0,
+- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+- if (hp2_pin_sense)
+- snd_hda_codec_write(codec, 0x16, 0,
+- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+-
+- if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
+- msleep(85);
++ if (hp1_pin_sense)
++ snd_hda_codec_write(codec, hp_pin, 0,
++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
++ if (hp2_pin_sense)
++ snd_hda_codec_write(codec, 0x16, 0,
++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+
+- if (hp1_pin_sense || spec->ultra_low_power)
+- snd_hda_codec_write(codec, hp_pin, 0,
+- AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+- if (hp2_pin_sense)
+- snd_hda_codec_write(codec, 0x16, 0,
+- AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
++ msleep(75);
+
+- if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
+- msleep(100);
++ if (hp1_pin_sense)
++ snd_hda_codec_write(codec, hp_pin, 0,
++ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
++ if (hp2_pin_sense)
++ snd_hda_codec_write(codec, 0x16, 0,
++ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+
++ msleep(75);
++ alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
++ alc_enable_headset_jack_key(codec);
++ }
+ alc_auto_setup_eapd(codec, false);
+ alc_shutup_pins(codec);
+ if (spec->ultra_low_power) {
+@@ -3839,9 +3831,6 @@ static void alc225_shutup(struct hda_codec *codec)
+ alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
+ msleep(30);
+ }
+-
+- alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
+- alc_enable_headset_jack_key(codec);
+ }
+
+ static void alc_default_init(struct hda_codec *codec)
+@@ -7265,6 +7254,8 @@ enum {
+ ALC290_FIXUP_SUBWOOFER_HSJACK,
+ ALC269_FIXUP_THINKPAD_ACPI,
+ ALC269_FIXUP_DMIC_THINKPAD_ACPI,
++ ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13,
++ ALC269VC_FIXUP_INFINIX_Y4_MAX,
+ ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO,
+ ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
+ ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
+@@ -7644,6 +7635,25 @@ static const struct hda_fixup alc269_fixups[] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
+ },
++ [ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13] = {
++ .type = HDA_FIXUP_PINS,
++ .v.pins = (const struct hda_pintbl[]) {
++ { 0x14, 0x90170151 }, /* use as internal speaker (LFE) */
++ { 0x1b, 0x90170152 }, /* use as internal speaker (back) */
++ { }
++ },
++ .chained = true,
++ .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
++ },
++ [ALC269VC_FIXUP_INFINIX_Y4_MAX] = {
++ .type = HDA_FIXUP_PINS,
++ .v.pins = (const struct hda_pintbl[]) {
++ { 0x1b, 0x90170150 }, /* use as internal speaker */
++ { }
++ },
++ .chained = true,
++ .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
++ },
+ [ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+@@ -10412,7 +10422,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
+ SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
++ SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
+ SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
++ SND_PCI_QUIRK(0x2782, 0x1701, "Infinix Y4 Max", ALC269VC_FIXUP_INFINIX_Y4_MAX),
++ SND_PCI_QUIRK(0x2782, 0x1705, "MEDION E15433", ALC269VC_FIXUP_INFINIX_Y4_MAX),
+ SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME),
+ SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
+ SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 08f823cd886999..a00933df9168ae 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -227,6 +227,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "21M3"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21M4"),
++ }
++ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+@@ -234,6 +241,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "21M5"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21ME"),
++ }
++ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+@@ -530,8 +544,14 @@ static int acp6x_probe(struct platform_device *pdev)
+ struct acp6x_pdm *machine = NULL;
+ struct snd_soc_card *card;
+ struct acpi_device *adev;
++ acpi_handle handle;
++ acpi_integer dmic_status;
+ int ret;
++ bool is_dmic_enable, wov_en;
+
++ /* IF WOV entry not found, enable dmic based on AcpDmicConnected entry*/
++ is_dmic_enable = false;
++ wov_en = true;
+ /* check the parent device's firmware node has _DSD or not */
+ adev = ACPI_COMPANION(pdev->dev.parent);
+ if (adev) {
+@@ -539,9 +559,19 @@ static int acp6x_probe(struct platform_device *pdev)
+
+ if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) &&
+ obj->integer.value == 1)
+- platform_set_drvdata(pdev, &acp6x_card);
++ is_dmic_enable = true;
+ }
+
++ handle = ACPI_HANDLE(pdev->dev.parent);
++ ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status);
++ if (!ACPI_FAILURE(ret))
++ wov_en = dmic_status;
++
++ if (is_dmic_enable && wov_en)
++ platform_set_drvdata(pdev, &acp6x_card);
++ else
++ return 0;
++
+ /* check for any DMI overrides */
+ dmi_id = dmi_first_match(yc_acp_quirk_table);
+ if (dmi_id)
+diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
+index 600c2db587568d..dd86033b707738 100644
+--- a/sound/soc/codecs/da7219.c
++++ b/sound/soc/codecs/da7219.c
+@@ -1167,17 +1167,20 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
+ int ret = 0;
+
+- if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
++ mutex_lock(&da7219->pll_lock);
++
++ if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) {
++ mutex_unlock(&da7219->pll_lock);
+ return 0;
++ }
+
+ if ((freq < 2000000) || (freq > 54000000)) {
++ mutex_unlock(&da7219->pll_lock);
+ dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
+ freq);
+ return -EINVAL;
+ }
+
+- mutex_lock(&da7219->pll_lock);
+-
+ switch (clk_id) {
+ case DA7219_CLKSRC_MCLK_SQR:
+ snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
+diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
+index e8cdc166bdaa99..1955d77cffd996 100644
+--- a/sound/soc/codecs/rt5640.c
++++ b/sound/soc/codecs/rt5640.c
+@@ -2422,10 +2422,20 @@ static irqreturn_t rt5640_jd_gpio_irq(int irq, void *data)
+ return IRQ_HANDLED;
+ }
+
+-static void rt5640_cancel_work(void *data)
++static void rt5640_disable_irq_and_cancel_work(void *data)
+ {
+ struct rt5640_priv *rt5640 = data;
+
++ if (rt5640->jd_gpio_irq_requested) {
++ free_irq(rt5640->jd_gpio_irq, rt5640);
++ rt5640->jd_gpio_irq_requested = false;
++ }
++
++ if (rt5640->irq_requested) {
++ free_irq(rt5640->irq, rt5640);
++ rt5640->irq_requested = false;
++ }
++
+ cancel_delayed_work_sync(&rt5640->jack_work);
+ cancel_delayed_work_sync(&rt5640->bp_work);
+ }
+@@ -2466,13 +2476,7 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
+ if (!rt5640->jack)
+ return;
+
+- if (rt5640->jd_gpio_irq_requested)
+- free_irq(rt5640->jd_gpio_irq, rt5640);
+-
+- if (rt5640->irq_requested)
+- free_irq(rt5640->irq, rt5640);
+-
+- rt5640_cancel_work(rt5640);
++ rt5640_disable_irq_and_cancel_work(rt5640);
+
+ if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+ rt5640_disable_micbias1_ovcd_irq(component);
+@@ -2480,8 +2484,6 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
+ snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
+ }
+
+- rt5640->jd_gpio_irq_requested = false;
+- rt5640->irq_requested = false;
+ rt5640->jd_gpio = NULL;
+ rt5640->jack = NULL;
+ }
+@@ -2801,7 +2803,8 @@ static int rt5640_suspend(struct snd_soc_component *component)
+ if (rt5640->jack) {
+ /* disable jack interrupts during system suspend */
+ disable_irq(rt5640->irq);
+- rt5640_cancel_work(rt5640);
++ cancel_delayed_work_sync(&rt5640->jack_work);
++ cancel_delayed_work_sync(&rt5640->bp_work);
+ }
+
+ snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
+@@ -3035,7 +3038,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c)
+ INIT_DELAYED_WORK(&rt5640->jack_work, rt5640_jack_work);
+
+ /* Make sure work is stopped on probe-error / remove */
+- ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
++ ret = devm_add_action_or_reset(&i2c->dev, rt5640_disable_irq_and_cancel_work, rt5640);
+ if (ret)
+ return ret;
+
+diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c
+index 9ff607984ea193..b9b330375addab 100644
+--- a/sound/soc/codecs/rt722-sdca.c
++++ b/sound/soc/codecs/rt722-sdca.c
+@@ -607,12 +607,8 @@ static int rt722_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol,
+
+ if (!adc_vol_flag) /* boost gain */
+ ctl = regvalue / boost_step;
+- else { /* ADC gain */
+- if (adc_vol_flag)
+- ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset);
+- else
+- ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset);
+- }
++ else /* ADC gain */
++ ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset);
+
+ ucontrol->value.integer.value[i] = ctl;
+ }
+diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c
+index 629e2195a890b2..1cc64ed8de6da8 100644
+--- a/sound/soc/codecs/tas2781-fmwlib.c
++++ b/sound/soc/codecs/tas2781-fmwlib.c
+@@ -2022,6 +2022,7 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw,
+ break;
+ case 0x202:
+ case 0x400:
++ case 0x401:
+ tas_priv->fw_parse_variable_header =
+ fw_parse_variable_header_git;
+ tas_priv->fw_parse_program_data =
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index 8478a4ac59f9dd..f57f0ab8a1add1 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -1051,7 +1051,7 @@ static irqreturn_t micfil_isr(int irq, void *devid)
+ regmap_write_bits(micfil->regmap,
+ REG_MICFIL_STAT,
+ MICFIL_STAT_CHXF(i),
+- 1);
++ MICFIL_STAT_CHXF(i));
+ }
+
+ for (i = 0; i < MICFIL_FIFO_NUM; i++) {
+@@ -1086,7 +1086,7 @@ static irqreturn_t micfil_err_isr(int irq, void *devid)
+ if (stat_reg & MICFIL_STAT_LOWFREQF) {
+ dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n");
+ regmap_write_bits(micfil->regmap, REG_MICFIL_STAT,
+- MICFIL_STAT_LOWFREQF, 1);
++ MICFIL_STAT_LOWFREQF, MICFIL_STAT_LOWFREQF);
+ }
+
+ return IRQ_HANDLED;
+diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c
+index b1c675c6b6db62..686e0dea2bc752 100644
+--- a/sound/soc/generic/audio-graph-card2.c
++++ b/sound/soc/generic/audio-graph-card2.c
+@@ -261,16 +261,19 @@ static enum graph_type __graph_get_type(struct device_node *lnk)
+
+ if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) {
+ ret = GRAPH_MULTI;
++ fw_devlink_purge_absent_suppliers(&np->fwnode);
+ goto out_put;
+ }
+
+ if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) {
+ ret = GRAPH_DPCM;
++ fw_devlink_purge_absent_suppliers(&np->fwnode);
+ goto out_put;
+ }
+
+ if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) {
+ ret = GRAPH_C2C;
++ fw_devlink_purge_absent_suppliers(&np->fwnode);
+ goto out_put;
+ }
+
+diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
+index 29d44c989e5fc2..cfa1632ae4f03f 100644
+--- a/sound/soc/intel/atom/sst/sst_acpi.c
++++ b/sound/soc/intel/atom/sst/sst_acpi.c
+@@ -125,6 +125,28 @@ static const struct sst_res_info bytcr_res_info = {
+ .acpi_ipc_irq_index = 0
+ };
+
++/* For "LPE0F28" ACPI device found on some Android factory OS models */
++static const struct sst_res_info lpe8086_res_info = {
++ .shim_offset = 0x140000,
++ .shim_size = 0x000100,
++ .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
++ .ssp0_offset = 0xa0000,
++ .ssp0_size = 0x1000,
++ .dma0_offset = 0x98000,
++ .dma0_size = 0x4000,
++ .dma1_offset = 0x9c000,
++ .dma1_size = 0x4000,
++ .iram_offset = 0x0c0000,
++ .iram_size = 0x14000,
++ .dram_offset = 0x100000,
++ .dram_size = 0x28000,
++ .mbox_offset = 0x144000,
++ .mbox_size = 0x1000,
++ .acpi_lpe_res_index = 1,
++ .acpi_ddr_index = 0,
++ .acpi_ipc_irq_index = 0
++};
++
+ static struct sst_platform_info byt_rvp_platform_data = {
+ .probe_data = &byt_fwparse_info,
+ .ipc_info = &byt_ipc_info,
+@@ -268,10 +290,38 @@ static int sst_acpi_probe(struct platform_device *pdev)
+ mach->pdata = &chv_platform_data;
+ pdata = mach->pdata;
+
+- ret = kstrtouint(id->id, 16, &dev_id);
+- if (ret < 0) {
+- dev_err(dev, "Unique device id conversion error: %d\n", ret);
+- return ret;
++ if (!strcmp(id->id, "LPE0F28")) {
++ struct resource *rsrc;
++
++ /* Use regular BYT SST PCI VID:PID */
++ dev_id = 0x80860F28;
++ byt_rvp_platform_data.res_info = &lpe8086_res_info;
++
++ /*
++ * The "LPE0F28" ACPI device has separate IO-mem resources for:
++ * DDR, SHIM, MBOX, IRAM, DRAM, CFG
++ * None of which covers the entire LPE base address range.
++ * lpe8086_res_info.acpi_lpe_res_index points to the SHIM.
++ * Patch this to cover the entire base address range as expected
++ * by sst_platform_get_resources().
++ */
++ rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
++ pdata->res_info->acpi_lpe_res_index);
++ if (!rsrc) {
++ dev_err(dev, "Invalid SHIM base\n");
++ return -EIO;
++ }
++ rsrc->start -= pdata->res_info->shim_offset;
++ rsrc->end = rsrc->start + 0x200000 - 1;
++ } else {
++ ret = kstrtouint(id->id, 16, &dev_id);
++ if (ret < 0) {
++ dev_err(dev, "Unique device id conversion error: %d\n", ret);
++ return ret;
++ }
++
++ if (soc_intel_is_byt_cr(pdev))
++ byt_rvp_platform_data.res_info = &bytcr_res_info;
+ }
+
+ dev_dbg(dev, "ACPI device id: %x\n", dev_id);
+@@ -280,11 +330,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
+ if (ret < 0)
+ return ret;
+
+- if (soc_intel_is_byt_cr(pdev)) {
+- /* override resource info */
+- byt_rvp_platform_data.res_info = &bytcr_res_info;
+- }
+-
+ /* update machine parameters */
+ mach->mach_params.acpi_ipc_irq_index =
+ pdata->res_info->acpi_ipc_irq_index;
+@@ -344,6 +389,7 @@ static void sst_acpi_remove(struct platform_device *pdev)
+ }
+
+ static const struct acpi_device_id sst_acpi_ids[] = {
++ { "LPE0F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
+ { "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
+ { "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines},
+ { },
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index 5b8b21ade9cfed..ddf68be0af14a5 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -17,6 +17,7 @@
+ #include <linux/acpi.h>
+ #include <linux/clk.h>
+ #include <linux/device.h>
++#include <linux/device/bus.h>
+ #include <linux/dmi.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/gpio/machine.h>
+@@ -32,6 +33,8 @@
+ #include "../atom/sst-atom-controls.h"
+ #include "../common/soc-intel-quirks.h"
+
++#define BYT_RT5640_FALLBACK_CODEC_DEV_NAME "i2c-rt5640"
++
+ enum {
+ BYT_RT5640_DMIC1_MAP,
+ BYT_RT5640_DMIC2_MAP,
+@@ -1129,6 +1132,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+ BYT_RT5640_SSP0_AIF2 |
+ BYT_RT5640_MCLK_EN),
+ },
++ { /* Vexia Edu Atla 10 tablet */
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
++ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
++ /* Above strings are too generic, also match on BIOS date */
++ DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
++ },
++ .driver_data = (void *)(BYT_RT5640_IN1_MAP |
++ BYT_RT5640_JD_SRC_JD2_IN4N |
++ BYT_RT5640_OVCD_TH_2000UA |
++ BYT_RT5640_OVCD_SF_0P75 |
++ BYT_RT5640_DIFF_MIC |
++ BYT_RT5640_SSP0_AIF2 |
++ BYT_RT5640_MCLK_EN),
++ },
+ { /* Voyo Winpad A15 */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+@@ -1697,9 +1715,33 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
+
+ codec_dev = acpi_get_first_physical_node(adev);
+ acpi_dev_put(adev);
+- if (!codec_dev)
+- return -EPROBE_DEFER;
+- priv->codec_dev = get_device(codec_dev);
++
++ if (codec_dev) {
++ priv->codec_dev = get_device(codec_dev);
++ } else {
++ /*
++ * Special case for Android tablets where the codec i2c_client
++ * has been manually instantiated by x86_android_tablets.ko due
++ * to a broken DSDT.
++ */
++ codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
++ BYT_RT5640_FALLBACK_CODEC_DEV_NAME);
++ if (!codec_dev)
++ return -EPROBE_DEFER;
++
++ if (!i2c_verify_client(codec_dev)) {
++ dev_err(dev, "Error '%s' is not an i2c_client\n",
++ BYT_RT5640_FALLBACK_CODEC_DEV_NAME);
++ put_device(codec_dev);
++ }
++
++ /* fixup codec name */
++ strscpy(byt_rt5640_codec_name, BYT_RT5640_FALLBACK_CODEC_DEV_NAME,
++ sizeof(byt_rt5640_codec_name));
++
++ /* bus_find_device() returns a reference no need to get() */
++ priv->codec_dev = codec_dev;
++ }
+
+ /*
+ * swap SSP0 if bytcr is detected
+diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
+index 0acc848c1f004d..dcbcd1a59a3aae 100644
+--- a/sound/soc/stm/stm32_sai_sub.c
++++ b/sound/soc/stm/stm32_sai_sub.c
+@@ -317,7 +317,7 @@ static int stm32_sai_get_clk_div(struct stm32_sai_sub_data *sai,
+ int div;
+
+ div = DIV_ROUND_CLOSEST(input_rate, output_rate);
+- if (div > SAI_XCR1_MCKDIV_MAX(version)) {
++ if (div > SAI_XCR1_MCKDIV_MAX(version) || div <= 0) {
+ dev_err(&sai->pdev->dev, "Divider %d out of range\n", div);
+ return -EINVAL;
+ }
+@@ -378,8 +378,8 @@ static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate,
+ int div;
+
+ div = stm32_sai_get_clk_div(sai, *prate, rate);
+- if (div < 0)
+- return div;
++ if (div <= 0)
++ return -EINVAL;
+
+ mclk->freq = *prate / div;
+
+diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
+index 33e962178c9363..d562a30b087f01 100644
+--- a/sound/usb/6fire/chip.c
++++ b/sound/usb/6fire/chip.c
+@@ -61,8 +61,10 @@ static void usb6fire_chip_abort(struct sfire_chip *chip)
+ }
+ }
+
+-static void usb6fire_chip_destroy(struct sfire_chip *chip)
++static void usb6fire_card_free(struct snd_card *card)
+ {
++ struct sfire_chip *chip = card->private_data;
++
+ if (chip) {
+ if (chip->pcm)
+ usb6fire_pcm_destroy(chip);
+@@ -72,8 +74,6 @@ static void usb6fire_chip_destroy(struct sfire_chip *chip)
+ usb6fire_comm_destroy(chip);
+ if (chip->control)
+ usb6fire_control_destroy(chip);
+- if (chip->card)
+- snd_card_free(chip->card);
+ }
+ }
+
+@@ -136,6 +136,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
+ chip->regidx = regidx;
+ chip->intf_count = 1;
+ chip->card = card;
++ card->private_free = usb6fire_card_free;
+
+ ret = usb6fire_comm_init(chip);
+ if (ret < 0)
+@@ -162,7 +163,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
+ return 0;
+
+ destroy_chip:
+- usb6fire_chip_destroy(chip);
++ snd_card_free(card);
+ return ret;
+ }
+
+@@ -181,7 +182,6 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)
+
+ chip->shutdown = true;
+ usb6fire_chip_abort(chip);
+- usb6fire_chip_destroy(chip);
+ }
+ }
+ }
+diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
+index 4981753652a7fe..7a89872aa0cbd6 100644
+--- a/sound/usb/caiaq/audio.c
++++ b/sound/usb/caiaq/audio.c
+@@ -869,14 +869,20 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev)
+ return 0;
+ }
+
+-void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev)
++void snd_usb_caiaq_audio_disconnect(struct snd_usb_caiaqdev *cdev)
+ {
+ struct device *dev = caiaqdev_to_dev(cdev);
+
+ dev_dbg(dev, "%s(%p)\n", __func__, cdev);
+ stream_stop(cdev);
++}
++
++void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev)
++{
++ struct device *dev = caiaqdev_to_dev(cdev);
++
++ dev_dbg(dev, "%s(%p)\n", __func__, cdev);
+ free_urbs(cdev->data_urbs_in);
+ free_urbs(cdev->data_urbs_out);
+ kfree(cdev->data_cb_info);
+ }
+-
+diff --git a/sound/usb/caiaq/audio.h b/sound/usb/caiaq/audio.h
+index 869bf6264d6a09..07f5d064456cf7 100644
+--- a/sound/usb/caiaq/audio.h
++++ b/sound/usb/caiaq/audio.h
+@@ -3,6 +3,7 @@
+ #define CAIAQ_AUDIO_H
+
+ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev);
++void snd_usb_caiaq_audio_disconnect(struct snd_usb_caiaqdev *cdev);
+ void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev);
+
+ #endif /* CAIAQ_AUDIO_H */
+diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
+index b5cbf1f195c48c..dfd820483849eb 100644
+--- a/sound/usb/caiaq/device.c
++++ b/sound/usb/caiaq/device.c
+@@ -376,6 +376,17 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
+ dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
+ }
+
++static void card_free(struct snd_card *card)
++{
++ struct snd_usb_caiaqdev *cdev = caiaqdev(card);
++
++#ifdef CONFIG_SND_USB_CAIAQ_INPUT
++ snd_usb_caiaq_input_free(cdev);
++#endif
++ snd_usb_caiaq_audio_free(cdev);
++ usb_reset_device(cdev->chip.dev);
++}
++
+ static int create_card(struct usb_device *usb_dev,
+ struct usb_interface *intf,
+ struct snd_card **cardp)
+@@ -489,6 +500,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
+ cdev->vendor_name, cdev->product_name, usbpath);
+
+ setup_card(cdev);
++ card->private_free = card_free;
+ return 0;
+
+ err_kill_urb:
+@@ -534,15 +546,14 @@ static void snd_disconnect(struct usb_interface *intf)
+ snd_card_disconnect(card);
+
+ #ifdef CONFIG_SND_USB_CAIAQ_INPUT
+- snd_usb_caiaq_input_free(cdev);
++ snd_usb_caiaq_input_disconnect(cdev);
+ #endif
+- snd_usb_caiaq_audio_free(cdev);
++ snd_usb_caiaq_audio_disconnect(cdev);
+
+ usb_kill_urb(&cdev->ep1_in_urb);
+ usb_kill_urb(&cdev->midi_out_urb);
+
+- snd_card_free(card);
+- usb_reset_device(interface_to_usbdev(intf));
++ snd_card_free_when_closed(card);
+ }
+
+
+diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
+index 84f26dce7f5d03..a9130891bb696d 100644
+--- a/sound/usb/caiaq/input.c
++++ b/sound/usb/caiaq/input.c
+@@ -829,15 +829,21 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
+ return ret;
+ }
+
+-void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev)
++void snd_usb_caiaq_input_disconnect(struct snd_usb_caiaqdev *cdev)
+ {
+ if (!cdev || !cdev->input_dev)
+ return;
+
+ usb_kill_urb(cdev->ep4_in_urb);
++ input_unregister_device(cdev->input_dev);
++}
++
++void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev)
++{
++ if (!cdev || !cdev->input_dev)
++ return;
++
+ usb_free_urb(cdev->ep4_in_urb);
+ cdev->ep4_in_urb = NULL;
+-
+- input_unregister_device(cdev->input_dev);
+ cdev->input_dev = NULL;
+ }
+diff --git a/sound/usb/caiaq/input.h b/sound/usb/caiaq/input.h
+index c42891e7be884d..fbe267f85d025f 100644
+--- a/sound/usb/caiaq/input.h
++++ b/sound/usb/caiaq/input.h
+@@ -4,6 +4,7 @@
+
+ void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev, char *buf, unsigned int len);
+ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev);
++void snd_usb_caiaq_input_disconnect(struct snd_usb_caiaqdev *cdev);
+ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev);
+
+ #endif
+diff --git a/sound/usb/clock.c b/sound/usb/clock.c
+index a676ad093d1897..f0f1e445cc5676 100644
+--- a/sound/usb/clock.c
++++ b/sound/usb/clock.c
+@@ -36,6 +36,12 @@ union uac23_clock_multiplier_desc {
+ struct uac_clock_multiplier_descriptor v3;
+ };
+
++/* check whether the descriptor bLength has the minimal length */
++#define DESC_LENGTH_CHECK(p, proto) \
++ ((proto) == UAC_VERSION_3 ? \
++ ((p)->v3.bLength >= sizeof((p)->v3)) : \
++ ((p)->v2.bLength >= sizeof((p)->v2)))
++
+ #define GET_VAL(p, proto, field) \
+ ((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field)
+
+@@ -58,6 +64,8 @@ static bool validate_clock_source(void *p, int id, int proto)
+ {
+ union uac23_clock_source_desc *cs = p;
+
++ if (!DESC_LENGTH_CHECK(cs, proto))
++ return false;
+ return GET_VAL(cs, proto, bClockID) == id;
+ }
+
+@@ -65,13 +73,27 @@ static bool validate_clock_selector(void *p, int id, int proto)
+ {
+ union uac23_clock_selector_desc *cs = p;
+
+- return GET_VAL(cs, proto, bClockID) == id;
++ if (!DESC_LENGTH_CHECK(cs, proto))
++ return false;
++ if (GET_VAL(cs, proto, bClockID) != id)
++ return false;
++ /* additional length check for baCSourceID array (in bNrInPins size)
++ * and two more fields (which sizes depend on the protocol)
++ */
++ if (proto == UAC_VERSION_3)
++ return cs->v3.bLength >= sizeof(cs->v3) + cs->v3.bNrInPins +
++ 4 /* bmControls */ + 2 /* wCSelectorDescrStr */;
++ else
++ return cs->v2.bLength >= sizeof(cs->v2) + cs->v2.bNrInPins +
++ 1 /* bmControls */ + 1 /* iClockSelector */;
+ }
+
+ static bool validate_clock_multiplier(void *p, int id, int proto)
+ {
+ union uac23_clock_multiplier_desc *cs = p;
+
++ if (!DESC_LENGTH_CHECK(cs, proto))
++ return false;
+ return GET_VAL(cs, proto, bClockID) == id;
+ }
+
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 75cde5779f38d5..d1bd8e0d602525 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -324,7 +324,6 @@ YAMAHA_DEVICE(0x105a, NULL),
+ YAMAHA_DEVICE(0x105b, NULL),
+ YAMAHA_DEVICE(0x105c, NULL),
+ YAMAHA_DEVICE(0x105d, NULL),
+-YAMAHA_DEVICE(0x1718, "P-125"),
+ {
+ USB_DEVICE(0x0499, 0x1503),
+ QUIRK_DRIVER_INFO {
+@@ -391,6 +390,19 @@ YAMAHA_DEVICE(0x1718, "P-125"),
+ }
+ }
+ },
++{
++ USB_DEVICE(0x0499, 0x1718),
++ QUIRK_DRIVER_INFO {
++ /* .vendor_name = "Yamaha", */
++ /* .product_name = "P-125", */
++ QUIRK_DATA_COMPOSITE {
++ { QUIRK_DATA_STANDARD_AUDIO(1) },
++ { QUIRK_DATA_STANDARD_AUDIO(2) },
++ { QUIRK_DATA_MIDI_YAMAHA(3) },
++ QUIRK_COMPOSITE_END
++ }
++ }
++},
+ YAMAHA_DEVICE(0x2000, "DGP-7"),
+ YAMAHA_DEVICE(0x2001, "DGP-5"),
+ YAMAHA_DEVICE(0x2002, NULL),
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 37211ad31ec894..30a4d2deefdab5 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -555,6 +555,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
+ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
+ {
+ struct usb_host_config *config = dev->actconfig;
++ struct usb_device_descriptor new_device_descriptor;
+ int err;
+
+ if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
+@@ -566,10 +567,14 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac
+ if (err < 0)
+ dev_dbg(&dev->dev, "error sending boot message: %d\n", err);
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
+- &dev->descriptor, sizeof(dev->descriptor));
+- config = dev->actconfig;
++ &new_device_descriptor, sizeof(new_device_descriptor));
+ if (err < 0)
+ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
++ if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations)
++ dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
++ new_device_descriptor.bNumConfigurations);
++ else
++ memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor));
+ err = usb_reset_configuration(dev);
+ if (err < 0)
+ dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
+@@ -901,6 +906,7 @@ static void mbox2_setup_48_24_magic(struct usb_device *dev)
+ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
+ {
+ struct usb_host_config *config = dev->actconfig;
++ struct usb_device_descriptor new_device_descriptor;
+ int err;
+ u8 bootresponse[0x12];
+ int fwsize;
+@@ -936,10 +942,14 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
+ dev_dbg(&dev->dev, "device initialised!\n");
+
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
+- &dev->descriptor, sizeof(dev->descriptor));
+- config = dev->actconfig;
++ &new_device_descriptor, sizeof(new_device_descriptor));
+ if (err < 0)
+ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
++ if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations)
++ dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
++ new_device_descriptor.bNumConfigurations);
++ else
++ memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor));
+
+ err = usb_reset_configuration(dev);
+ if (err < 0)
+@@ -1253,6 +1263,7 @@ static void mbox3_setup_48_24_magic(struct usb_device *dev)
+ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
+ {
+ struct usb_host_config *config = dev->actconfig;
++ struct usb_device_descriptor new_device_descriptor;
+ int err;
+ int descriptor_size;
+
+@@ -1266,10 +1277,14 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
+ dev_dbg(&dev->dev, "device initialised!\n");
+
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
+- &dev->descriptor, sizeof(dev->descriptor));
+- config = dev->actconfig;
++ &new_device_descriptor, sizeof(new_device_descriptor));
+ if (err < 0)
+ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
++ if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations)
++ dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
++ new_device_descriptor.bNumConfigurations);
++ else
++ memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor));
+
+ err = usb_reset_configuration(dev);
+ if (err < 0)
+diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
+index 709ccad972e2ff..612047ca5fe7ac 100644
+--- a/sound/usb/usx2y/us122l.c
++++ b/sound/usb/usx2y/us122l.c
+@@ -617,10 +617,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
+ usb_put_intf(usb_ifnum_to_if(us122l->dev, 1));
+ usb_put_dev(us122l->dev);
+
+- while (atomic_read(&us122l->mmap_count))
+- msleep(500);
+-
+- snd_card_free(card);
++ snd_card_free_when_closed(card);
+ }
+
+ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
+diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
+index 52f4e6652407d5..4c4ce0319d624d 100644
+--- a/sound/usb/usx2y/usbusx2y.c
++++ b/sound/usb/usx2y/usbusx2y.c
+@@ -423,7 +423,7 @@ static void snd_usx2y_disconnect(struct usb_interface *intf)
+ }
+ if (usx2y->us428ctls_sharedmem)
+ wake_up(&usx2y->us428ctls_wait_queue_head);
+- snd_card_free(card);
++ snd_card_free_when_closed(card);
+ }
+
+ static int snd_usx2y_probe(struct usb_interface *intf,
+diff --git a/tools/bpf/bpftool/jit_disasm.c b/tools/bpf/bpftool/jit_disasm.c
+index 7b8d9ec89ebd35..c032d2c6ab6d55 100644
+--- a/tools/bpf/bpftool/jit_disasm.c
++++ b/tools/bpf/bpftool/jit_disasm.c
+@@ -80,7 +80,8 @@ symbol_lookup_callback(__maybe_unused void *disasm_info,
+ static int
+ init_context(disasm_ctx_t *ctx, const char *arch,
+ __maybe_unused const char *disassembler_options,
+- __maybe_unused unsigned char *image, __maybe_unused ssize_t len)
++ __maybe_unused unsigned char *image, __maybe_unused ssize_t len,
++ __maybe_unused __u64 func_ksym)
+ {
+ char *triple;
+
+@@ -109,12 +110,13 @@ static void destroy_context(disasm_ctx_t *ctx)
+ }
+
+ static int
+-disassemble_insn(disasm_ctx_t *ctx, unsigned char *image, ssize_t len, int pc)
++disassemble_insn(disasm_ctx_t *ctx, unsigned char *image, ssize_t len, int pc,
++ __u64 func_ksym)
+ {
+ char buf[256];
+ int count;
+
+- count = LLVMDisasmInstruction(*ctx, image + pc, len - pc, pc,
++ count = LLVMDisasmInstruction(*ctx, image + pc, len - pc, func_ksym + pc,
+ buf, sizeof(buf));
+ if (json_output)
+ printf_json(buf);
+@@ -136,8 +138,21 @@ int disasm_init(void)
+ #ifdef HAVE_LIBBFD_SUPPORT
+ #define DISASM_SPACER "\t"
+
++struct disasm_info {
++ struct disassemble_info info;
++ __u64 func_ksym;
++};
++
++static void disasm_print_addr(bfd_vma addr, struct disassemble_info *info)
++{
++ struct disasm_info *dinfo = container_of(info, struct disasm_info, info);
++
++ addr += dinfo->func_ksym;
++ generic_print_address(addr, info);
++}
++
+ typedef struct {
+- struct disassemble_info *info;
++ struct disasm_info *info;
+ disassembler_ftype disassemble;
+ bfd *bfdf;
+ } disasm_ctx_t;
+@@ -215,7 +230,7 @@ static int fprintf_json_styled(void *out,
+
+ static int init_context(disasm_ctx_t *ctx, const char *arch,
+ const char *disassembler_options,
+- unsigned char *image, ssize_t len)
++ unsigned char *image, ssize_t len, __u64 func_ksym)
+ {
+ struct disassemble_info *info;
+ char tpath[PATH_MAX];
+@@ -238,12 +253,13 @@ static int init_context(disasm_ctx_t *ctx, const char *arch,
+ }
+ bfdf = ctx->bfdf;
+
+- ctx->info = malloc(sizeof(struct disassemble_info));
++ ctx->info = malloc(sizeof(struct disasm_info));
+ if (!ctx->info) {
+ p_err("mem alloc failed");
+ goto err_close;
+ }
+- info = ctx->info;
++ ctx->info->func_ksym = func_ksym;
++ info = &ctx->info->info;
+
+ if (json_output)
+ init_disassemble_info_compat(info, stdout,
+@@ -272,6 +288,7 @@ static int init_context(disasm_ctx_t *ctx, const char *arch,
+ info->disassembler_options = disassembler_options;
+ info->buffer = image;
+ info->buffer_length = len;
++ info->print_address_func = disasm_print_addr;
+
+ disassemble_init_for_target(info);
+
+@@ -304,9 +321,10 @@ static void destroy_context(disasm_ctx_t *ctx)
+
+ static int
+ disassemble_insn(disasm_ctx_t *ctx, __maybe_unused unsigned char *image,
+- __maybe_unused ssize_t len, int pc)
++ __maybe_unused ssize_t len, int pc,
++ __maybe_unused __u64 func_ksym)
+ {
+- return ctx->disassemble(pc, ctx->info);
++ return ctx->disassemble(pc, &ctx->info->info);
+ }
+
+ int disasm_init(void)
+@@ -331,7 +349,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
+ if (!len)
+ return -1;
+
+- if (init_context(&ctx, arch, disassembler_options, image, len))
++ if (init_context(&ctx, arch, disassembler_options, image, len, func_ksym))
+ return -1;
+
+ if (json_output)
+@@ -360,7 +378,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
+ printf("%4x:" DISASM_SPACER, pc);
+ }
+
+- count = disassemble_insn(&ctx, image, len, pc);
++ count = disassemble_insn(&ctx, image, len, pc, func_ksym);
+
+ if (json_output) {
+ /* Operand array, was started in fprintf_json. Before
+diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h
+index 5d60fd43f88309..f72df614db3a24 100644
+--- a/tools/include/nolibc/arch-s390.h
++++ b/tools/include/nolibc/arch-s390.h
+@@ -10,6 +10,7 @@
+
+ #include "compiler.h"
+ #include "crt.h"
++#include "std.h"
+
+ /* Syscalls for s390:
+ * - registers are 64-bit
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index ceed16a10285ab..2fad178949efe9 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -3586,7 +3586,7 @@ static bool sym_is_subprog(const Elf64_Sym *sym, int text_shndx)
+ return true;
+
+ /* global function */
+- return bind == STB_GLOBAL && type == STT_FUNC;
++ return (bind == STB_GLOBAL || bind == STB_WEAK) && type == STT_FUNC;
+ }
+
+ static int find_extern_btf_id(const struct btf *btf, const char *ext_name)
+@@ -3990,7 +3990,7 @@ static int bpf_object__collect_externs(struct bpf_object *obj)
+
+ static bool prog_is_subprog(const struct bpf_object *obj, const struct bpf_program *prog)
+ {
+- return prog->sec_idx == obj->efile.text_shndx && obj->nr_programs > 1;
++ return prog->sec_idx == obj->efile.text_shndx;
+ }
+
+ struct bpf_program *
+@@ -6837,8 +6837,14 @@ static int libbpf_prepare_prog_load(struct bpf_program *prog,
+ opts->prog_flags |= BPF_F_XDP_HAS_FRAGS;
+
+ /* special check for usdt to use uprobe_multi link */
+- if ((def & SEC_USDT) && kernel_supports(prog->obj, FEAT_UPROBE_MULTI_LINK))
++ if ((def & SEC_USDT) && kernel_supports(prog->obj, FEAT_UPROBE_MULTI_LINK)) {
++ /* for BPF_TRACE_UPROBE_MULTI, user might want to query expected_attach_type
++ * in prog, and expected_attach_type we set in kernel is from opts, so we
++ * update both.
++ */
+ prog->expected_attach_type = BPF_TRACE_UPROBE_MULTI;
++ opts->expected_attach_type = BPF_TRACE_UPROBE_MULTI;
++ }
+
+ if ((def & SEC_ATTACH_BTF) && !prog->attach_btf_id) {
+ int btf_obj_fd = 0, btf_type_id = 0, err;
+@@ -6915,6 +6921,7 @@ static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog
+ load_attr.attach_btf_id = prog->attach_btf_id;
+ load_attr.kern_version = kern_version;
+ load_attr.prog_ifindex = prog->prog_ifindex;
++ load_attr.expected_attach_type = prog->expected_attach_type;
+
+ /* specify func_info/line_info only if kernel supports them */
+ btf_fd = bpf_object__btf_fd(obj);
+@@ -6943,9 +6950,6 @@ static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog
+ insns_cnt = prog->insns_cnt;
+ }
+
+- /* allow prog_prepare_load_fn to change expected_attach_type */
+- load_attr.expected_attach_type = prog->expected_attach_type;
+-
+ if (obj->gen_loader) {
+ bpf_gen__prog_load(obj->gen_loader, prog->type, prog->name,
+ license, insns, insns_cnt, &load_attr,
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
+index b311bb91f672e5..88cc7236f12202 100644
+--- a/tools/lib/bpf/linker.c
++++ b/tools/lib/bpf/linker.c
+@@ -396,6 +396,8 @@ static int init_output_elf(struct bpf_linker *linker, const char *file)
+ pr_warn_elf("failed to create SYMTAB data");
+ return -EINVAL;
+ }
++ /* Ensure libelf translates byte-order of symbol records */
++ sec->data->d_type = ELF_T_SYM;
+
+ str_off = strset__add_str(linker->strtab_strs, sec->sec_name);
+ if (str_off < 0)
+diff --git a/tools/lib/thermal/Makefile b/tools/lib/thermal/Makefile
+index 2d0d255fd0e1c4..8890fd57b110cc 100644
+--- a/tools/lib/thermal/Makefile
++++ b/tools/lib/thermal/Makefile
+@@ -121,7 +121,9 @@ all: fixdep
+
+ clean:
+ $(call QUIET_CLEAN, libthermal) $(RM) $(LIBTHERMAL_A) \
+- *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBTHERMAL_VERSION) .*.d .*.cmd LIBTHERMAL-CFLAGS $(LIBTHERMAL_PC)
++ *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBTHERMAL_VERSION) \
++ .*.d .*.cmd LIBTHERMAL-CFLAGS $(LIBTHERMAL_PC) \
++ $(srctree)/tools/$(THERMAL_UAPI)
+
+ $(LIBTHERMAL_PC):
+ $(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \
+diff --git a/tools/lib/thermal/commands.c b/tools/lib/thermal/commands.c
+index 73d4d4e8d6ec0b..27b4442f0e347a 100644
+--- a/tools/lib/thermal/commands.c
++++ b/tools/lib/thermal/commands.c
+@@ -261,9 +261,25 @@ static struct genl_ops thermal_cmd_ops = {
+ .o_ncmds = ARRAY_SIZE(thermal_cmds),
+ };
+
+-static thermal_error_t thermal_genl_auto(struct thermal_handler *th, int id, int cmd,
+- int flags, void *arg)
++struct cmd_param {
++ int tz_id;
++};
++
++typedef int (*cmd_cb_t)(struct nl_msg *, struct cmd_param *);
++
++static int thermal_genl_tz_id_encode(struct nl_msg *msg, struct cmd_param *p)
++{
++ if (p->tz_id >= 0 && nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id))
++ return -1;
++
++ return 0;
++}
++
++static thermal_error_t thermal_genl_auto(struct thermal_handler *th, cmd_cb_t cmd_cb,
++ struct cmd_param *param,
++ int cmd, int flags, void *arg)
+ {
++ thermal_error_t ret = THERMAL_ERROR;
+ struct nl_msg *msg;
+ void *hdr;
+
+@@ -274,45 +290,55 @@ static thermal_error_t thermal_genl_auto(struct thermal_handler *th, int id, int
+ hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, thermal_cmd_ops.o_id,
+ 0, flags, cmd, THERMAL_GENL_VERSION);
+ if (!hdr)
+- return THERMAL_ERROR;
++ goto out;
+
+- if (id >= 0 && nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id))
+- return THERMAL_ERROR;
++ if (cmd_cb && cmd_cb(msg, param))
++ goto out;
+
+ if (nl_send_msg(th->sk_cmd, th->cb_cmd, msg, genl_handle_msg, arg))
+- return THERMAL_ERROR;
++ goto out;
+
++ ret = THERMAL_SUCCESS;
++out:
+ nlmsg_free(msg);
+
+- return THERMAL_SUCCESS;
++ return ret;
+ }
+
+ thermal_error_t thermal_cmd_get_tz(struct thermal_handler *th, struct thermal_zone **tz)
+ {
+- return thermal_genl_auto(th, -1, THERMAL_GENL_CMD_TZ_GET_ID,
++ return thermal_genl_auto(th, NULL, NULL, THERMAL_GENL_CMD_TZ_GET_ID,
+ NLM_F_DUMP | NLM_F_ACK, tz);
+ }
+
+ thermal_error_t thermal_cmd_get_cdev(struct thermal_handler *th, struct thermal_cdev **tc)
+ {
+- return thermal_genl_auto(th, -1, THERMAL_GENL_CMD_CDEV_GET,
++ return thermal_genl_auto(th, NULL, NULL, THERMAL_GENL_CMD_CDEV_GET,
+ NLM_F_DUMP | NLM_F_ACK, tc);
+ }
+
+ thermal_error_t thermal_cmd_get_trip(struct thermal_handler *th, struct thermal_zone *tz)
+ {
+- return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_TRIP,
+- 0, tz);
++ struct cmd_param p = { .tz_id = tz->id };
++
++ return thermal_genl_auto(th, thermal_genl_tz_id_encode, &p,
++ THERMAL_GENL_CMD_TZ_GET_TRIP, 0, tz);
+ }
+
+ thermal_error_t thermal_cmd_get_governor(struct thermal_handler *th, struct thermal_zone *tz)
+ {
+- return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_GOV, 0, tz);
++ struct cmd_param p = { .tz_id = tz->id };
++
++ return thermal_genl_auto(th, thermal_genl_tz_id_encode, &p,
++ THERMAL_GENL_CMD_TZ_GET_GOV, 0, tz);
+ }
+
+ thermal_error_t thermal_cmd_get_temp(struct thermal_handler *th, struct thermal_zone *tz)
+ {
+- return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_TEMP, 0, tz);
++ struct cmd_param p = { .tz_id = tz->id };
++
++ return thermal_genl_auto(th, thermal_genl_tz_id_encode, &p,
++ THERMAL_GENL_CMD_TZ_GET_TEMP, 0, tz);
+ }
+
+ thermal_error_t thermal_cmd_exit(struct thermal_handler *th)
+diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
+index ac2e6c75f91201..a1971703e49cb8 100644
+--- a/tools/perf/builtin-ftrace.c
++++ b/tools/perf/builtin-ftrace.c
+@@ -771,7 +771,7 @@ static void display_histogram(int buckets[], bool use_nsec)
+
+ bar_len = buckets[0] * bar_total / total;
+ printf(" %4d - %-4d %s | %10d | %.*s%*s |\n",
+- 0, 1, "us", buckets[0], bar_len, bar, bar_total - bar_len, "");
++ 0, 1, use_nsec ? "ns" : "us", buckets[0], bar_len, bar, bar_total - bar_len, "");
+
+ for (i = 1; i < NUM_BUCKET - 1; i++) {
+ int start = (1 << (i - 1));
+diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
+index 61c2c96cc0701b..c8c72fcf37e116 100644
+--- a/tools/perf/builtin-list.c
++++ b/tools/perf/builtin-list.c
+@@ -95,7 +95,7 @@ static void wordwrap(const char *s, int start, int max, int corr)
+ }
+ }
+
+-static void default_print_event(void *ps, const char *pmu_name, const char *topic,
++static void default_print_event(void *ps, const char *topic, const char *pmu_name,
+ const char *event_name, const char *event_alias,
+ const char *scale_unit __maybe_unused,
+ bool deprecated, const char *event_type_desc,
+@@ -321,7 +321,7 @@ static void fix_escape_printf(struct strbuf *buf, const char *fmt, ...)
+ fputs(buf->buf, stdout);
+ }
+
+-static void json_print_event(void *ps, const char *pmu_name, const char *topic,
++static void json_print_event(void *ps, const char *topic, const char *pmu_name,
+ const char *event_name, const char *event_alias,
+ const char *scale_unit,
+ bool deprecated, const char *event_type_desc,
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index 78c10492218102..9692ebdd7f11e9 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -712,15 +712,19 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ }
+
+ if (!cpu_map__is_dummy(evsel_list->core.user_requested_cpus)) {
+- if (affinity__setup(&saved_affinity) < 0)
+- return -1;
++ if (affinity__setup(&saved_affinity) < 0) {
++ err = -1;
++ goto err_out;
++ }
+ affinity = &saved_affinity;
+ }
+
+ evlist__for_each_entry(evsel_list, counter) {
+ counter->reset_group = false;
+- if (bpf_counter__load(counter, &target))
+- return -1;
++ if (bpf_counter__load(counter, &target)) {
++ err = -1;
++ goto err_out;
++ }
+ if (!(evsel__is_bperf(counter)))
+ all_counters_use_bpf = false;
+ }
+@@ -763,7 +767,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+
+ switch (stat_handle_error(counter)) {
+ case COUNTER_FATAL:
+- return -1;
++ err = -1;
++ goto err_out;
+ case COUNTER_RETRY:
+ goto try_again;
+ case COUNTER_SKIP:
+@@ -804,7 +809,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+
+ switch (stat_handle_error(counter)) {
+ case COUNTER_FATAL:
+- return -1;
++ err = -1;
++ goto err_out;
+ case COUNTER_RETRY:
+ goto try_again_reset;
+ case COUNTER_SKIP:
+@@ -817,6 +823,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ }
+ }
+ affinity__cleanup(affinity);
++ affinity = NULL;
+
+ evlist__for_each_entry(evsel_list, counter) {
+ if (!counter->supported) {
+@@ -829,8 +836,10 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ stat_config.unit_width = l;
+
+ if (evsel__should_store_id(counter) &&
+- evsel__store_ids(counter, evsel_list))
+- return -1;
++ evsel__store_ids(counter, evsel_list)) {
++ err = -1;
++ goto err_out;
++ }
+ }
+
+ if (evlist__apply_filters(evsel_list, &counter)) {
+@@ -851,20 +860,23 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ }
+
+ if (err < 0)
+- return err;
++ goto err_out;
+
+ err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list,
+ process_synthesized_event, is_pipe);
+ if (err < 0)
+- return err;
++ goto err_out;
++
+ }
+
+ if (target.initial_delay) {
+ pr_info(EVLIST_DISABLED_MSG);
+ } else {
+ err = enable_counters();
+- if (err)
+- return -1;
++ if (err) {
++ err = -1;
++ goto err_out;
++ }
+ }
+
+ /* Exec the command, if any */
+@@ -874,8 +886,10 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ if (target.initial_delay > 0) {
+ usleep(target.initial_delay * USEC_PER_MSEC);
+ err = enable_counters();
+- if (err)
+- return -1;
++ if (err) {
++ err = -1;
++ goto err_out;
++ }
+
+ pr_info(EVLIST_ENABLED_MSG);
+ }
+@@ -895,7 +909,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ if (workload_exec_errno) {
+ const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
+ pr_err("Workload failed: %s\n", emsg);
+- return -1;
++ err = -1;
++ goto err_out;
+ }
+
+ if (WIFSIGNALED(status))
+@@ -942,6 +957,13 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ evlist__close(evsel_list);
+
+ return WEXITSTATUS(status);
++
++err_out:
++ if (forks)
++ evlist__cancel_workload(evsel_list);
++
++ affinity__cleanup(affinity);
++ return err;
+ }
+
+ static int run_perf_stat(int argc, const char **argv, int run_idx)
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index e541d0e2777ab9..3ecd6868be2d6d 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -2414,6 +2414,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
+ char msg[1024];
+ void *args, *augmented_args = NULL;
+ int augmented_args_size;
++ size_t printed = 0;
+
+ if (sc == NULL)
+ return -1;
+@@ -2429,8 +2430,8 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
+
+ args = perf_evsel__sc_tp_ptr(evsel, args, sample);
+ augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls_args_size);
+- syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread);
+- fprintf(trace->output, "%s", msg);
++ printed += syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread);
++ fprintf(trace->output, "%.*s", (int)printed, msg);
+ err = 0;
+ out_put:
+ thread__put(thread);
+@@ -2803,7 +2804,7 @@ static size_t trace__fprintf_tp_fields(struct trace *trace, struct evsel *evsel,
+ printed += syscall_arg_fmt__scnprintf_val(arg, bf + printed, size - printed, &syscall_arg, val);
+ }
+
+- return printed + fprintf(trace->output, "%s", bf);
++ return printed + fprintf(trace->output, "%.*s", (int)printed, bf);
+ }
+
+ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
+@@ -2812,13 +2813,8 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
+ {
+ struct thread *thread;
+ int callchain_ret = 0;
+- /*
+- * Check if we called perf_evsel__disable(evsel) due to, for instance,
+- * this event's max_events having been hit and this is an entry coming
+- * from the ring buffer that we should discard, since the max events
+- * have already been considered/printed.
+- */
+- if (evsel->disabled)
++
++ if (evsel->nr_events_printed >= evsel->max_events)
+ return 0;
+
+ thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
+@@ -3923,6 +3919,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
+ sizeof(__u32), BPF_ANY);
+ }
+ }
++
++ if (trace->skel)
++ trace->filter_pids.map = trace->skel->maps.pids_filtered;
+ #endif
+ err = trace__set_filter_pids(trace);
+ if (err < 0)
+@@ -5031,6 +5030,10 @@ int cmd_trace(int argc, const char **argv)
+ if (trace.summary_only)
+ trace.summary = trace.summary_only;
+
++ /* Keep exited threads, otherwise information might be lost for summary */
++ if (trace.summary)
++ symbol_conf.keep_exited_threads = true;
++
+ if (output_name != NULL) {
+ err = trace__open_output(&trace, output_name);
+ if (err < 0) {
+diff --git a/tools/perf/tests/attr/test-stat-default b/tools/perf/tests/attr/test-stat-default
+index a1e2da0a9a6ddb..e47fb49446799b 100644
+--- a/tools/perf/tests/attr/test-stat-default
++++ b/tools/perf/tests/attr/test-stat-default
+@@ -88,98 +88,142 @@ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
++# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+ [event13:base-stat]
+ fd=13
+ group_fd=11
+ type=4
+-config=33280
++config=33024
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-be-bound (0x8300)
++# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+ [event14:base-stat]
+ fd=14
+ group_fd=11
+ type=4
+-config=33536
++config=33280
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
++# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+ [event15:base-stat]
+ fd=15
+ group_fd=11
+ type=4
+-config=33024
++config=33536
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
++# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+ [event16:base-stat]
+ fd=16
++group_fd=11
+ type=4
+-config=4109
++config=33792
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
++# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+ [event17:base-stat]
+ fd=17
++group_fd=11
+ type=4
+-config=17039629
++config=34048
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
++# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+ [event18:base-stat]
+ fd=18
++group_fd=11
+ type=4
+-config=60
++config=34304
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
++# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+ [event19:base-stat]
+ fd=19
++group_fd=11
+ type=4
+-config=2097421
++config=34560
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
++# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+ [event20:base-stat]
+ fd=20
+ type=4
+-config=316
++config=4109
+ optional=1
+
+-# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+ [event21:base-stat]
+ fd=21
+ type=4
+-config=412
++config=17039629
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+ [event22:base-stat]
+ fd=22
+ type=4
+-config=572
++config=60
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+ [event23:base-stat]
+ fd=23
+ type=4
+-config=706
++config=2097421
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+ [event24:base-stat]
+ fd=24
+ type=4
++config=316
++optional=1
++
++# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++[event25:base-stat]
++fd=25
++type=4
++config=412
++optional=1
++
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++[event26:base-stat]
++fd=26
++type=4
++config=572
++optional=1
++
++# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++[event27:base-stat]
++fd=27
++type=4
++config=706
++optional=1
++
++# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++[event28:base-stat]
++fd=28
++type=4
+ config=270
+ optional=1
+diff --git a/tools/perf/tests/attr/test-stat-detailed-1 b/tools/perf/tests/attr/test-stat-detailed-1
+index 1c52cb05c900d7..3d500d3e0c5c8a 100644
+--- a/tools/perf/tests/attr/test-stat-detailed-1
++++ b/tools/perf/tests/attr/test-stat-detailed-1
+@@ -90,99 +90,143 @@ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
++# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+ [event13:base-stat]
+ fd=13
+ group_fd=11
+ type=4
+-config=33280
++config=33024
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-be-bound (0x8300)
++# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+ [event14:base-stat]
+ fd=14
+ group_fd=11
+ type=4
+-config=33536
++config=33280
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
++# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+ [event15:base-stat]
+ fd=15
+ group_fd=11
+ type=4
+-config=33024
++config=33536
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
++# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+ [event16:base-stat]
+ fd=16
++group_fd=11
+ type=4
+-config=4109
++config=33792
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
++# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+ [event17:base-stat]
+ fd=17
++group_fd=11
+ type=4
+-config=17039629
++config=34048
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
++# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+ [event18:base-stat]
+ fd=18
++group_fd=11
+ type=4
+-config=60
++config=34304
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
++# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+ [event19:base-stat]
+ fd=19
++group_fd=11
+ type=4
+-config=2097421
++config=34560
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
++# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+ [event20:base-stat]
+ fd=20
+ type=4
+-config=316
++config=4109
+ optional=1
+
+-# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+ [event21:base-stat]
+ fd=21
+ type=4
+-config=412
++config=17039629
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+ [event22:base-stat]
+ fd=22
+ type=4
+-config=572
++config=60
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+ [event23:base-stat]
+ fd=23
+ type=4
+-config=706
++config=2097421
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+ [event24:base-stat]
+ fd=24
+ type=4
++config=316
++optional=1
++
++# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++[event25:base-stat]
++fd=25
++type=4
++config=412
++optional=1
++
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++[event26:base-stat]
++fd=26
++type=4
++config=572
++optional=1
++
++# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++[event27:base-stat]
++fd=27
++type=4
++config=706
++optional=1
++
++# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++[event28:base-stat]
++fd=28
++type=4
+ config=270
+ optional=1
+
+@@ -190,8 +234,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event25:base-stat]
+-fd=25
++[event29:base-stat]
++fd=29
+ type=3
+ config=0
+ optional=1
+@@ -200,8 +244,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event26:base-stat]
+-fd=26
++[event30:base-stat]
++fd=30
+ type=3
+ config=65536
+ optional=1
+@@ -210,8 +254,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_LL << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event27:base-stat]
+-fd=27
++[event31:base-stat]
++fd=31
+ type=3
+ config=2
+ optional=1
+@@ -220,8 +264,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_LL << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event28:base-stat]
+-fd=28
++[event32:base-stat]
++fd=32
+ type=3
+ config=65538
+ optional=1
+diff --git a/tools/perf/tests/attr/test-stat-detailed-2 b/tools/perf/tests/attr/test-stat-detailed-2
+index 7e961d24a885a7..01777a63752fe6 100644
+--- a/tools/perf/tests/attr/test-stat-detailed-2
++++ b/tools/perf/tests/attr/test-stat-detailed-2
+@@ -90,99 +90,143 @@ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
++# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+ [event13:base-stat]
+ fd=13
+ group_fd=11
+ type=4
+-config=33280
++config=33024
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-be-bound (0x8300)
++# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+ [event14:base-stat]
+ fd=14
+ group_fd=11
+ type=4
+-config=33536
++config=33280
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
++# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+ [event15:base-stat]
+ fd=15
+ group_fd=11
+ type=4
+-config=33024
++config=33536
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
++# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+ [event16:base-stat]
+ fd=16
++group_fd=11
+ type=4
+-config=4109
++config=33792
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
++# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+ [event17:base-stat]
+ fd=17
++group_fd=11
+ type=4
+-config=17039629
++config=34048
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
++# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+ [event18:base-stat]
+ fd=18
++group_fd=11
+ type=4
+-config=60
++config=34304
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
++# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+ [event19:base-stat]
+ fd=19
++group_fd=11
+ type=4
+-config=2097421
++config=34560
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
++# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+ [event20:base-stat]
+ fd=20
+ type=4
+-config=316
++config=4109
+ optional=1
+
+-# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+ [event21:base-stat]
+ fd=21
+ type=4
+-config=412
++config=17039629
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+ [event22:base-stat]
+ fd=22
+ type=4
+-config=572
++config=60
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+ [event23:base-stat]
+ fd=23
+ type=4
+-config=706
++config=2097421
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+ [event24:base-stat]
+ fd=24
+ type=4
++config=316
++optional=1
++
++# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++[event25:base-stat]
++fd=25
++type=4
++config=412
++optional=1
++
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++[event26:base-stat]
++fd=26
++type=4
++config=572
++optional=1
++
++# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++[event27:base-stat]
++fd=27
++type=4
++config=706
++optional=1
++
++# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++[event28:base-stat]
++fd=28
++type=4
+ config=270
+ optional=1
+
+@@ -190,8 +234,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event25:base-stat]
+-fd=25
++[event29:base-stat]
++fd=29
+ type=3
+ config=0
+ optional=1
+@@ -200,8 +244,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event26:base-stat]
+-fd=26
++[event30:base-stat]
++fd=30
+ type=3
+ config=65536
+ optional=1
+@@ -210,8 +254,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_LL << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event27:base-stat]
+-fd=27
++[event31:base-stat]
++fd=31
+ type=3
+ config=2
+ optional=1
+@@ -220,8 +264,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_LL << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event28:base-stat]
+-fd=28
++[event32:base-stat]
++fd=32
+ type=3
+ config=65538
+ optional=1
+@@ -230,8 +274,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1I << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event29:base-stat]
+-fd=29
++[event33:base-stat]
++fd=33
+ type=3
+ config=1
+ optional=1
+@@ -240,8 +284,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1I << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event30:base-stat]
+-fd=30
++[event34:base-stat]
++fd=34
+ type=3
+ config=65537
+ optional=1
+@@ -250,8 +294,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_DTLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event31:base-stat]
+-fd=31
++[event35:base-stat]
++fd=35
+ type=3
+ config=3
+ optional=1
+@@ -260,8 +304,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_DTLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event32:base-stat]
+-fd=32
++[event36:base-stat]
++fd=36
+ type=3
+ config=65539
+ optional=1
+@@ -270,8 +314,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_ITLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event33:base-stat]
+-fd=33
++[event37:base-stat]
++fd=37
+ type=3
+ config=4
+ optional=1
+@@ -280,8 +324,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_ITLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event34:base-stat]
+-fd=34
++[event38:base-stat]
++fd=38
+ type=3
+ config=65540
+ optional=1
+diff --git a/tools/perf/tests/attr/test-stat-detailed-3 b/tools/perf/tests/attr/test-stat-detailed-3
+index e50535f45977c6..8400abd7e1e488 100644
+--- a/tools/perf/tests/attr/test-stat-detailed-3
++++ b/tools/perf/tests/attr/test-stat-detailed-3
+@@ -90,99 +90,143 @@ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
++# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+ [event13:base-stat]
+ fd=13
+ group_fd=11
+ type=4
+-config=33280
++config=33024
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-be-bound (0x8300)
++# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+ [event14:base-stat]
+ fd=14
+ group_fd=11
+ type=4
+-config=33536
++config=33280
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
++# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+ [event15:base-stat]
+ fd=15
+ group_fd=11
+ type=4
+-config=33024
++config=33536
+ disabled=0
+ enable_on_exec=0
+ read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
++# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+ [event16:base-stat]
+ fd=16
++group_fd=11
+ type=4
+-config=4109
++config=33792
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
++# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+ [event17:base-stat]
+ fd=17
++group_fd=11
+ type=4
+-config=17039629
++config=34048
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
++# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+ [event18:base-stat]
+ fd=18
++group_fd=11
+ type=4
+-config=60
++config=34304
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
++# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+ [event19:base-stat]
+ fd=19
++group_fd=11
+ type=4
+-config=2097421
++config=34560
++disabled=0
++enable_on_exec=0
++read_format=15
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
++# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING
+ [event20:base-stat]
+ fd=20
+ type=4
+-config=316
++config=4109
+ optional=1
+
+-# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/
+ [event21:base-stat]
+ fd=21
+ type=4
+-config=412
++config=17039629
+ optional=1
+
+-# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD
+ [event22:base-stat]
+ fd=22
+ type=4
+-config=572
++config=60
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY
+ [event23:base-stat]
+ fd=23
+ type=4
+-config=706
++config=2097421
+ optional=1
+
+-# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK
+ [event24:base-stat]
+ fd=24
+ type=4
++config=316
++optional=1
++
++# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE
++[event25:base-stat]
++fd=25
++type=4
++config=412
++optional=1
++
++# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE
++[event26:base-stat]
++fd=26
++type=4
++config=572
++optional=1
++
++# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS
++[event27:base-stat]
++fd=27
++type=4
++config=706
++optional=1
++
++# PERF_TYPE_RAW / UOPS_ISSUED.ANY
++[event28:base-stat]
++fd=28
++type=4
+ config=270
+ optional=1
+
+@@ -190,8 +234,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event25:base-stat]
+-fd=25
++[event29:base-stat]
++fd=29
+ type=3
+ config=0
+ optional=1
+@@ -200,8 +244,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event26:base-stat]
+-fd=26
++[event30:base-stat]
++fd=30
+ type=3
+ config=65536
+ optional=1
+@@ -210,8 +254,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_LL << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event27:base-stat]
+-fd=27
++[event31:base-stat]
++fd=31
+ type=3
+ config=2
+ optional=1
+@@ -220,8 +264,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_LL << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event28:base-stat]
+-fd=28
++[event32:base-stat]
++fd=32
+ type=3
+ config=65538
+ optional=1
+@@ -230,8 +274,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1I << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event29:base-stat]
+-fd=29
++[event33:base-stat]
++fd=33
+ type=3
+ config=1
+ optional=1
+@@ -240,8 +284,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1I << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event30:base-stat]
+-fd=30
++[event34:base-stat]
++fd=34
+ type=3
+ config=65537
+ optional=1
+@@ -250,8 +294,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_DTLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event31:base-stat]
+-fd=31
++[event35:base-stat]
++fd=35
+ type=3
+ config=3
+ optional=1
+@@ -260,8 +304,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_DTLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event32:base-stat]
+-fd=32
++[event36:base-stat]
++fd=36
+ type=3
+ config=65539
+ optional=1
+@@ -270,8 +314,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_ITLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event33:base-stat]
+-fd=33
++[event37:base-stat]
++fd=37
+ type=3
+ config=4
+ optional=1
+@@ -280,8 +324,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_ITLB << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event34:base-stat]
+-fd=34
++[event38:base-stat]
++fd=38
+ type=3
+ config=65540
+ optional=1
+@@ -290,8 +334,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
+-[event35:base-stat]
+-fd=35
++[event39:base-stat]
++fd=39
+ type=3
+ config=512
+ optional=1
+@@ -300,8 +344,8 @@ optional=1
+ # PERF_COUNT_HW_CACHE_L1D << 0 |
+ # (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+ # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
+-[event36:base-stat]
+-fd=36
++[event40:base-stat]
++fd=40
+ type=3
+ config=66048
+ optional=1
+diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
+index 9729d006550d98..799c104901b4ff 100644
+--- a/tools/perf/util/cs-etm.c
++++ b/tools/perf/util/cs-etm.c
+@@ -2412,12 +2412,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
+
+ /* Ignore return value */
+ cs_etm__process_traceid_queue(etmq, tidq);
+-
+- /*
+- * Generate an instruction sample with the remaining
+- * branchstack entries.
+- */
+- cs_etm__flush(etmq, tidq);
+ }
+ }
+
+@@ -2560,7 +2554,7 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
+
+ while (1) {
+ if (!etm->heap.heap_cnt)
+- goto out;
++ break;
+
+ /* Take the entry at the top of the min heap */
+ cs_queue_nr = etm->heap.heap_array[0].queue_nr;
+@@ -2643,6 +2637,23 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
+ ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
+ }
+
++ for (i = 0; i < etm->queues.nr_queues; i++) {
++ struct int_node *inode;
++
++ etmq = etm->queues.queue_array[i].priv;
++ if (!etmq)
++ continue;
++
++ intlist__for_each_entry(inode, etmq->traceid_queues_list) {
++ int idx = (int)(intptr_t)inode->priv;
++
++ /* Flush any remaining branch stack entries */
++ tidq = etmq->traceid_queues[idx];
++ ret = cs_etm__end_block(etmq, tidq);
++ if (ret)
++ return ret;
++ }
++ }
+ out:
+ return ret;
+ }
+diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
+index eb1dd29c538d5c..1eadb4f7c1b9dc 100644
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -46,6 +46,7 @@
+ #include <sys/mman.h>
+ #include <sys/prctl.h>
+ #include <sys/timerfd.h>
++#include <sys/wait.h>
+
+ #include <linux/bitops.h>
+ #include <linux/hash.h>
+@@ -1412,6 +1413,8 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const
+ int child_ready_pipe[2], go_pipe[2];
+ char bf;
+
++ evlist->workload.cork_fd = -1;
++
+ if (pipe(child_ready_pipe) < 0) {
+ perror("failed to create 'ready' pipe");
+ return -1;
+@@ -1464,7 +1467,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const
+ * For cancelling the workload without actually running it,
+ * the parent will just close workload.cork_fd, without writing
+ * anything, i.e. read will return zero and we just exit()
+- * here.
++ * here (See evlist__cancel_workload()).
+ */
+ if (ret != 1) {
+ if (ret == -1)
+@@ -1528,7 +1531,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const
+
+ int evlist__start_workload(struct evlist *evlist)
+ {
+- if (evlist->workload.cork_fd > 0) {
++ if (evlist->workload.cork_fd >= 0) {
+ char bf = 0;
+ int ret;
+ /*
+@@ -1539,12 +1542,24 @@ int evlist__start_workload(struct evlist *evlist)
+ perror("unable to write to pipe");
+
+ close(evlist->workload.cork_fd);
++ evlist->workload.cork_fd = -1;
+ return ret;
+ }
+
+ return 0;
+ }
+
++void evlist__cancel_workload(struct evlist *evlist)
++{
++ int status;
++
++ if (evlist->workload.cork_fd >= 0) {
++ close(evlist->workload.cork_fd);
++ evlist->workload.cork_fd = -1;
++ waitpid(evlist->workload.pid, &status, WNOHANG);
++ }
++}
++
+ int evlist__parse_sample(struct evlist *evlist, union perf_event *event, struct perf_sample *sample)
+ {
+ struct evsel *evsel = evlist__event2evsel(evlist, event);
+diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
+index cb91dc9117a272..12f929ffdf920d 100644
+--- a/tools/perf/util/evlist.h
++++ b/tools/perf/util/evlist.h
+@@ -184,6 +184,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target,
+ const char *argv[], bool pipe_output,
+ void (*exec_error)(int signo, siginfo_t *info, void *ucontext));
+ int evlist__start_workload(struct evlist *evlist);
++void evlist__cancel_workload(struct evlist *evlist);
+
+ struct option;
+
+diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c
+index 862e4a689868b6..54421fceef5c7f 100644
+--- a/tools/perf/util/pfm.c
++++ b/tools/perf/util/pfm.c
+@@ -220,7 +220,7 @@ print_libpfm_event(const struct print_callbacks *print_cb, void *print_state,
+ }
+
+ if (is_libpfm_event_supported(name, cpus, threads)) {
+- print_cb->print_event(print_state, pinfo->name, topic,
++ print_cb->print_event(print_state, topic, pinfo->name,
+ name, info->equiv,
+ /*scale_unit=*/NULL,
+ /*deprecated=*/NULL, "PFM event",
+@@ -254,8 +254,8 @@ print_libpfm_event(const struct print_callbacks *print_cb, void *print_state,
+ continue;
+
+ print_cb->print_event(print_state,
+- pinfo->name,
+ topic,
++ pinfo->name,
+ name, /*alias=*/NULL,
+ /*scale_unit=*/NULL,
+ /*deprecated=*/NULL, "PFM event",
+diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
+index 54a237b2b85386..f0577aa7eca885 100644
+--- a/tools/perf/util/pmus.c
++++ b/tools/perf/util/pmus.c
+@@ -474,8 +474,8 @@ void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, void *p
+ goto free;
+
+ print_cb->print_event(print_state,
+- aliases[j].pmu_name,
+ aliases[j].topic,
++ aliases[j].pmu_name,
+ aliases[j].name,
+ aliases[j].alias,
+ aliases[j].scale_unit,
+diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
+index f171360b0ef4db..c0c8d7f9514b04 100644
+--- a/tools/perf/util/probe-finder.c
++++ b/tools/perf/util/probe-finder.c
+@@ -1499,6 +1499,10 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
+ if (ret >= 0 && tf.pf.skip_empty_arg)
+ ret = fill_empty_trace_arg(pev, tf.tevs, tf.ntevs);
+
++#if _ELFUTILS_PREREQ(0, 142)
++ dwarf_cfi_end(tf.pf.cfi_eh);
++#endif
++
+ if (ret < 0 || tf.ntevs == 0) {
+ for (i = 0; i < tf.ntevs; i++)
+ clear_probe_trace_event(&tf.tevs[i]);
+@@ -1741,8 +1745,21 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
+
+ /* Find a corresponding function (name, baseline and baseaddr) */
+ if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
+- /* Get function entry information */
+- func = basefunc = dwarf_diename(&spdie);
++ /*
++ * Get function entry information.
++ *
++ * As described in the document DWARF Debugging Information
++ * Format Version 5, section 2.22 Linkage Names, "mangled names,
++ * are used in various ways, ... to distinguish multiple
++ * entities that have the same name".
++ *
++ * Firstly try to get distinct linkage name, if fail then
++ * rollback to get associated name in DIE.
++ */
++ func = basefunc = die_get_linkage_name(&spdie);
++ if (!func)
++ func = basefunc = dwarf_diename(&spdie);
++
+ if (!func ||
+ die_entrypc(&spdie, &baseaddr) != 0 ||
+ dwarf_decl_line(&spdie, &baseline) != 0) {
+diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
+index 8bc1c80d3c1c0b..1f4650b955094f 100644
+--- a/tools/perf/util/probe-finder.h
++++ b/tools/perf/util/probe-finder.h
+@@ -81,9 +81,9 @@ struct probe_finder {
+
+ /* For variable searching */
+ #if _ELFUTILS_PREREQ(0, 142)
+- /* Call Frame Information from .eh_frame */
++ /* Call Frame Information from .eh_frame. Owned by this struct. */
+ Dwarf_CFI *cfi_eh;
+- /* Call Frame Information from .debug_frame */
++ /* Call Frame Information from .debug_frame. Not owned. */
+ Dwarf_CFI *cfi_dbg;
+ #endif
+ Dwarf_Op *fb_ops; /* Frame base attribute */
+diff --git a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
+index 2b1425b92b6991..a3d1e23fe02aff 100644
+--- a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
++++ b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
+@@ -65,7 +65,7 @@ static int check_single_included_tags(int mem_type, int mode)
+ ptr = mte_insert_tags(ptr, BUFFER_SIZE);
+ /* Check tag value */
+ if (MT_FETCH_TAG((uintptr_t)ptr) == tag) {
+- ksft_print_msg("FAIL: wrong tag = 0x%x with include mask=0x%x\n",
++ ksft_print_msg("FAIL: wrong tag = 0x%lx with include mask=0x%x\n",
+ MT_FETCH_TAG((uintptr_t)ptr),
+ MT_INCLUDE_VALID_TAG(tag));
+ result = KSFT_FAIL;
+@@ -97,7 +97,7 @@ static int check_multiple_included_tags(int mem_type, int mode)
+ ptr = mte_insert_tags(ptr, BUFFER_SIZE);
+ /* Check tag value */
+ if (MT_FETCH_TAG((uintptr_t)ptr) < tag) {
+- ksft_print_msg("FAIL: wrong tag = 0x%x with include mask=0x%x\n",
++ ksft_print_msg("FAIL: wrong tag = 0x%lx with include mask=0x%lx\n",
+ MT_FETCH_TAG((uintptr_t)ptr),
+ MT_INCLUDE_VALID_TAGS(excl_mask));
+ result = KSFT_FAIL;
+diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
+index 00ffd34c66d301..1120f5aa76550f 100644
+--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
++++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
+@@ -38,7 +38,7 @@ void mte_default_handler(int signum, siginfo_t *si, void *uc)
+ if (cur_mte_cxt.trig_si_code == si->si_code)
+ cur_mte_cxt.fault_valid = true;
+ else
+- ksft_print_msg("Got unexpected SEGV_MTEAERR at pc=$lx, fault addr=%lx\n",
++ ksft_print_msg("Got unexpected SEGV_MTEAERR at pc=%llx, fault addr=%lx\n",
+ ((ucontext_t *)uc)->uc_mcontext.pc,
+ addr);
+ return;
+@@ -64,7 +64,7 @@ void mte_default_handler(int signum, siginfo_t *si, void *uc)
+ exit(1);
+ }
+ } else if (signum == SIGBUS) {
+- ksft_print_msg("INFO: SIGBUS signal at pc=%lx, fault addr=%lx, si_code=%lx\n",
++ ksft_print_msg("INFO: SIGBUS signal at pc=%llx, fault addr=%lx, si_code=%x\n",
+ ((ucontext_t *)uc)->uc_mcontext.pc, addr, si->si_code);
+ if ((cur_mte_cxt.trig_range >= 0 &&
+ addr >= MT_CLEAR_TAG(cur_mte_cxt.trig_addr) &&
+diff --git a/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c b/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c
+index 86cd183ef6dc8a..293ac1049d3889 100644
+--- a/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c
++++ b/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c
+@@ -28,8 +28,8 @@ struct {
+ },
+ };
+
+-SEC(".data.A") struct bpf_spin_lock lockA;
+-SEC(".data.B") struct bpf_spin_lock lockB;
++static struct bpf_spin_lock lockA SEC(".data.A");
++static struct bpf_spin_lock lockB SEC(".data.B");
+
+ SEC("?tc")
+ int lock_id_kptr_preserve(void *ctx)
+diff --git a/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c
+index f61d623b1ce8df..f87365f7599bf7 100644
+--- a/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c
++++ b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c
+@@ -541,11 +541,24 @@ static __u64 subprog_spill_reg_precise(void)
+
+ SEC("?raw_tp")
+ __success __log_level(2)
+-/* precision backtracking can't currently handle stack access not through r10,
+- * so we won't be able to mark stack slot fp-8 as precise, and so will
+- * fallback to forcing all as precise
+- */
+-__msg("mark_precise: frame0: falling back to forcing all scalars precise")
++__msg("10: (0f) r1 += r7")
++__msg("mark_precise: frame0: last_idx 10 first_idx 7 subseq_idx -1")
++__msg("mark_precise: frame0: regs=r7 stack= before 9: (bf) r1 = r8")
++__msg("mark_precise: frame0: regs=r7 stack= before 8: (27) r7 *= 4")
++__msg("mark_precise: frame0: regs=r7 stack= before 7: (79) r7 = *(u64 *)(r10 -8)")
++__msg("mark_precise: frame0: parent state regs= stack=-8: R0_w=2 R6_w=1 R8_rw=map_value(map=.data.vals,ks=4,vs=16) R10=fp0 fp-8_rw=P1")
++__msg("mark_precise: frame0: last_idx 18 first_idx 0 subseq_idx 7")
++__msg("mark_precise: frame0: regs= stack=-8 before 18: (95) exit")
++__msg("mark_precise: frame1: regs= stack= before 17: (0f) r0 += r2")
++__msg("mark_precise: frame1: regs= stack= before 16: (79) r2 = *(u64 *)(r1 +0)")
++__msg("mark_precise: frame1: regs= stack= before 15: (79) r0 = *(u64 *)(r10 -16)")
++__msg("mark_precise: frame1: regs= stack= before 14: (7b) *(u64 *)(r10 -16) = r2")
++__msg("mark_precise: frame1: regs= stack= before 13: (7b) *(u64 *)(r1 +0) = r2")
++__msg("mark_precise: frame1: regs=r2 stack= before 6: (85) call pc+6")
++__msg("mark_precise: frame0: regs=r2 stack= before 5: (bf) r2 = r6")
++__msg("mark_precise: frame0: regs=r6 stack= before 4: (07) r1 += -8")
++__msg("mark_precise: frame0: regs=r6 stack= before 3: (bf) r1 = r10")
++__msg("mark_precise: frame0: regs=r6 stack= before 2: (b7) r6 = 1")
+ __naked int subprog_spill_into_parent_stack_slot_precise(void)
+ {
+ asm volatile (
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index a181c0ccf98b2a..dccaf9b8cb900b 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -56,6 +56,8 @@ static void running_handler(int a);
+ #define BPF_SOCKHASH_FILENAME "test_sockhash_kern.bpf.o"
+ #define CG_PATH "/sockmap"
+
++#define EDATAINTEGRITY 2001
++
+ /* global sockets */
+ int s1, s2, c1, c2, p1, p2;
+ int test_cnt;
+@@ -85,6 +87,10 @@ int ktls;
+ int peek_flag;
+ int skb_use_parser;
+ int txmsg_omit_skb_parser;
++int verify_push_start;
++int verify_push_len;
++int verify_pop_start;
++int verify_pop_len;
+
+ static const struct option long_options[] = {
+ {"help", no_argument, NULL, 'h' },
+@@ -417,16 +423,18 @@ static int msg_loop_sendpage(int fd, int iov_length, int cnt,
+ {
+ bool drop = opt->drop_expected;
+ unsigned char k = 0;
++ int i, j, fp;
+ FILE *file;
+- int i, fp;
+
+ file = tmpfile();
+ if (!file) {
+ perror("create file for sendpage");
+ return 1;
+ }
+- for (i = 0; i < iov_length * cnt; i++, k++)
+- fwrite(&k, sizeof(char), 1, file);
++ for (i = 0; i < cnt; i++, k = 0) {
++ for (j = 0; j < iov_length; j++, k++)
++ fwrite(&k, sizeof(char), 1, file);
++ }
+ fflush(file);
+ fseek(file, 0, SEEK_SET);
+
+@@ -509,42 +517,111 @@ static int msg_alloc_iov(struct msghdr *msg,
+ return -ENOMEM;
+ }
+
+-static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz)
++/* In push or pop test, we need to do some calculations for msg_verify_data */
++static void msg_verify_date_prep(void)
+ {
+- int i, j = 0, bytes_cnt = 0;
+- unsigned char k = 0;
++ int push_range_end = txmsg_start_push + txmsg_end_push - 1;
++ int pop_range_end = txmsg_start_pop + txmsg_pop - 1;
++
++ if (txmsg_end_push && txmsg_pop &&
++ txmsg_start_push <= pop_range_end && txmsg_start_pop <= push_range_end) {
++ /* The push range and the pop range overlap */
++ int overlap_len;
++
++ verify_push_start = txmsg_start_push;
++ verify_pop_start = txmsg_start_pop;
++ if (txmsg_start_push < txmsg_start_pop)
++ overlap_len = min(push_range_end - txmsg_start_pop + 1, txmsg_pop);
++ else
++ overlap_len = min(pop_range_end - txmsg_start_push + 1, txmsg_end_push);
++ verify_push_len = max(txmsg_end_push - overlap_len, 0);
++ verify_pop_len = max(txmsg_pop - overlap_len, 0);
++ } else {
++ /* Otherwise */
++ verify_push_start = txmsg_start_push;
++ verify_pop_start = txmsg_start_pop;
++ verify_push_len = txmsg_end_push;
++ verify_pop_len = txmsg_pop;
++ }
++}
++
++static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
++ unsigned char *k_p, int *bytes_cnt_p,
++ int *check_cnt_p, int *push_p)
++{
++ int bytes_cnt = *bytes_cnt_p, check_cnt = *check_cnt_p, push = *push_p;
++ unsigned char k = *k_p;
++ int i, j;
+
+- for (i = 0; i < msg->msg_iovlen; i++) {
++ for (i = 0, j = 0; i < msg->msg_iovlen && size; i++, j = 0) {
+ unsigned char *d = msg->msg_iov[i].iov_base;
+
+ /* Special case test for skb ingress + ktls */
+ if (i == 0 && txmsg_ktls_skb) {
+ if (msg->msg_iov[i].iov_len < 4)
+- return -EIO;
++ return -EDATAINTEGRITY;
+ if (memcmp(d, "PASS", 4) != 0) {
+ fprintf(stderr,
+ "detected skb data error with skb ingress update @iov[%i]:%i \"%02x %02x %02x %02x\" != \"PASS\"\n",
+ i, 0, d[0], d[1], d[2], d[3]);
+- return -EIO;
++ return -EDATAINTEGRITY;
+ }
+ j = 4; /* advance index past PASS header */
+ }
+
+ for (; j < msg->msg_iov[i].iov_len && size; j++) {
++ if (push > 0 &&
++ check_cnt == verify_push_start + verify_push_len - push) {
++ int skipped;
++revisit_push:
++ skipped = push;
++ if (j + push >= msg->msg_iov[i].iov_len)
++ skipped = msg->msg_iov[i].iov_len - j;
++ push -= skipped;
++ size -= skipped;
++ j += skipped - 1;
++ check_cnt += skipped;
++ continue;
++ }
++
++ if (verify_pop_len > 0 && check_cnt == verify_pop_start) {
++ bytes_cnt += verify_pop_len;
++ check_cnt += verify_pop_len;
++ k += verify_pop_len;
++
++ if (bytes_cnt == chunk_sz) {
++ k = 0;
++ bytes_cnt = 0;
++ check_cnt = 0;
++ push = verify_push_len;
++ }
++
++ if (push > 0 &&
++ check_cnt == verify_push_start + verify_push_len - push)
++ goto revisit_push;
++ }
++
+ if (d[j] != k++) {
+ fprintf(stderr,
+ "detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n",
+ i, j, d[j], k - 1, d[j+1], k);
+- return -EIO;
++ return -EDATAINTEGRITY;
+ }
+ bytes_cnt++;
++ check_cnt++;
+ if (bytes_cnt == chunk_sz) {
+ k = 0;
+ bytes_cnt = 0;
++ check_cnt = 0;
++ push = verify_push_len;
+ }
+ size--;
+ }
+ }
++ *k_p = k;
++ *bytes_cnt_p = bytes_cnt;
++ *check_cnt_p = check_cnt;
++ *push_p = push;
+ return 0;
+ }
+
+@@ -597,10 +674,14 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+ }
+ clock_gettime(CLOCK_MONOTONIC, &s->end);
+ } else {
++ float total_bytes, txmsg_pop_total, txmsg_push_total;
+ int slct, recvp = 0, recv, max_fd = fd;
+- float total_bytes, txmsg_pop_total;
+ int fd_flags = O_NONBLOCK;
+ struct timeval timeout;
++ unsigned char k = 0;
++ int bytes_cnt = 0;
++ int check_cnt = 0;
++ int push = 0;
+ fd_set w;
+
+ fcntl(fd, fd_flags);
+@@ -614,12 +695,22 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+ * This is really only useful for testing edge cases in code
+ * paths.
+ */
+- total_bytes = (float)iov_count * (float)iov_length * (float)cnt;
+- if (txmsg_apply)
++ total_bytes = (float)iov_length * (float)cnt;
++ if (!opt->sendpage)
++ total_bytes *= (float)iov_count;
++ if (txmsg_apply) {
++ txmsg_push_total = txmsg_end_push * (total_bytes / txmsg_apply);
+ txmsg_pop_total = txmsg_pop * (total_bytes / txmsg_apply);
+- else
++ } else {
++ txmsg_push_total = txmsg_end_push * cnt;
+ txmsg_pop_total = txmsg_pop * cnt;
++ }
++ total_bytes += txmsg_push_total;
+ total_bytes -= txmsg_pop_total;
++ if (data) {
++ msg_verify_date_prep();
++ push = verify_push_len;
++ }
+ err = clock_gettime(CLOCK_MONOTONIC, &s->start);
+ if (err < 0)
+ perror("recv start time");
+@@ -692,10 +783,11 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+
+ if (data) {
+ int chunk_sz = opt->sendpage ?
+- iov_length * cnt :
++ iov_length :
+ iov_length * iov_count;
+
+- errno = msg_verify_data(&msg, recv, chunk_sz);
++ errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt,
++ &check_cnt, &push);
+ if (errno) {
+ perror("data verify msg failed");
+ goto out_errno;
+@@ -703,7 +795,11 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+ if (recvp) {
+ errno = msg_verify_data(&msg_peek,
+ recvp,
+- chunk_sz);
++ chunk_sz,
++ &k,
++ &bytes_cnt,
++ &check_cnt,
++ &push);
+ if (errno) {
+ perror("data verify msg_peek failed");
+ goto out_errno;
+@@ -785,8 +881,6 @@ static int sendmsg_test(struct sockmap_options *opt)
+
+ rxpid = fork();
+ if (rxpid == 0) {
+- if (txmsg_pop || txmsg_start_pop)
+- iov_buf -= (txmsg_pop - txmsg_start_pop + 1);
+ if (opt->drop_expected || txmsg_ktls_skb_drop)
+ _exit(0);
+
+@@ -811,7 +905,7 @@ static int sendmsg_test(struct sockmap_options *opt)
+ s.bytes_sent, sent_Bps, sent_Bps/giga,
+ s.bytes_recvd, recvd_Bps, recvd_Bps/giga,
+ peek_flag ? "(peek_msg)" : "");
+- if (err && txmsg_cork)
++ if (err && err != -EDATAINTEGRITY && txmsg_cork)
+ err = 0;
+ exit(err ? 1 : 0);
+ } else if (rxpid == -1) {
+@@ -1459,8 +1553,8 @@ static void test_send_many(struct sockmap_options *opt, int cgrp)
+
+ static void test_send_large(struct sockmap_options *opt, int cgrp)
+ {
+- opt->iov_length = 256;
+- opt->iov_count = 1024;
++ opt->iov_length = 8192;
++ opt->iov_count = 32;
+ opt->rate = 2;
+ test_exec(cgrp, opt);
+ }
+@@ -1589,17 +1683,19 @@ static void test_txmsg_cork_hangs(int cgrp, struct sockmap_options *opt)
+ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt)
+ {
+ /* Test basic start/end */
++ txmsg_pass = 1;
+ txmsg_start = 1;
+ txmsg_end = 2;
+ test_send(opt, cgrp);
+
+ /* Test >4k pull */
++ txmsg_pass = 1;
+ txmsg_start = 4096;
+ txmsg_end = 9182;
+ test_send_large(opt, cgrp);
+
+ /* Test pull + redirect */
+- txmsg_redir = 0;
++ txmsg_redir = 1;
+ txmsg_start = 1;
+ txmsg_end = 2;
+ test_send(opt, cgrp);
+@@ -1621,12 +1717,16 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt)
+
+ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+ {
++ bool data = opt->data_test;
++
+ /* Test basic pop */
++ txmsg_pass = 1;
+ txmsg_start_pop = 1;
+ txmsg_pop = 2;
+ test_send_many(opt, cgrp);
+
+ /* Test pop with >4k */
++ txmsg_pass = 1;
+ txmsg_start_pop = 4096;
+ txmsg_pop = 4096;
+ test_send_large(opt, cgrp);
+@@ -1637,6 +1737,12 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+ txmsg_pop = 2;
+ test_send_many(opt, cgrp);
+
++ /* TODO: Test for pop + cork should be different,
++ * - It makes the layout of the received data difficult
++ * - It makes it hard to calculate the total_bytes in the recvmsg
++ * Temporarily skip the data integrity test for this case now.
++ */
++ opt->data_test = false;
+ /* Test pop + cork */
+ txmsg_redir = 0;
+ txmsg_cork = 512;
+@@ -1650,16 +1756,21 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+ txmsg_start_pop = 1;
+ txmsg_pop = 2;
+ test_send_many(opt, cgrp);
++ opt->data_test = data;
+ }
+
+ static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
+ {
++ bool data = opt->data_test;
++
+ /* Test basic push */
++ txmsg_pass = 1;
+ txmsg_start_push = 1;
+ txmsg_end_push = 1;
+ test_send(opt, cgrp);
+
+ /* Test push 4kB >4k */
++ txmsg_pass = 1;
+ txmsg_start_push = 4096;
+ txmsg_end_push = 4096;
+ test_send_large(opt, cgrp);
+@@ -1670,16 +1781,24 @@ static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
+ txmsg_end_push = 2;
+ test_send_many(opt, cgrp);
+
++ /* TODO: Test for push + cork should be different,
++ * - It makes the layout of the received data difficult
++ * - It makes it hard to calculate the total_bytes in the recvmsg
++ * Temporarily skip the data integrity test for this case now.
++ */
++ opt->data_test = false;
+ /* Test push + cork */
+ txmsg_redir = 0;
+ txmsg_cork = 512;
+ txmsg_start_push = 1;
+ txmsg_end_push = 2;
+ test_send_many(opt, cgrp);
++ opt->data_test = data;
+ }
+
+ static void test_txmsg_push_pop(int cgrp, struct sockmap_options *opt)
+ {
++ txmsg_pass = 1;
+ txmsg_start_push = 1;
+ txmsg_end_push = 10;
+ txmsg_start_pop = 5;
+diff --git a/tools/testing/selftests/bpf/verifier/precise.c b/tools/testing/selftests/bpf/verifier/precise.c
+index 0d84dd1f38b6b0..8a2ff81d835088 100644
+--- a/tools/testing/selftests/bpf/verifier/precise.c
++++ b/tools/testing/selftests/bpf/verifier/precise.c
+@@ -140,10 +140,11 @@
+ .result = REJECT,
+ },
+ {
+- "precise: ST insn causing spi > allocated_stack",
++ "precise: ST zero to stack insn is supported",
+ .insns = {
+ BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0),
++ /* not a register spill, so we stop precision propagation for R4 here */
+ BPF_ST_MEM(BPF_DW, BPF_REG_3, -8, 0),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
+ BPF_MOV64_IMM(BPF_REG_0, -1),
+@@ -157,11 +158,11 @@
+ mark_precise: frame0: last_idx 4 first_idx 2\
+ mark_precise: frame0: regs=r4 stack= before 4\
+ mark_precise: frame0: regs=r4 stack= before 3\
+- mark_precise: frame0: regs= stack=-8 before 2\
+- mark_precise: frame0: falling back to forcing all scalars precise\
+- force_precise: frame0: forcing r0 to be precise\
+ mark_precise: frame0: last_idx 5 first_idx 5\
+- mark_precise: frame0: parent state regs= stack=:",
++ mark_precise: frame0: parent state regs=r0 stack=:\
++ mark_precise: frame0: last_idx 4 first_idx 2\
++ mark_precise: frame0: regs=r0 stack= before 4\
++ 5: R0=-1 R4=0",
+ .result = VERBOSE_ACCEPT,
+ .retval = -1,
+ },
+@@ -169,6 +170,8 @@
+ "precise: STX insn causing spi > allocated_stack",
+ .insns = {
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
++ /* make later reg spill more interesting by having somewhat known scalar */
++ BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
+ BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0),
+ BPF_STX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, -8),
+@@ -179,18 +182,21 @@
+ },
+ .prog_type = BPF_PROG_TYPE_XDP,
+ .flags = BPF_F_TEST_STATE_FREQ,
+- .errstr = "mark_precise: frame0: last_idx 6 first_idx 6\
++ .errstr = "mark_precise: frame0: last_idx 7 first_idx 7\
+ mark_precise: frame0: parent state regs=r4 stack=:\
+- mark_precise: frame0: last_idx 5 first_idx 3\
+- mark_precise: frame0: regs=r4 stack= before 5\
+- mark_precise: frame0: regs=r4 stack= before 4\
+- mark_precise: frame0: regs= stack=-8 before 3\
+- mark_precise: frame0: falling back to forcing all scalars precise\
+- force_precise: frame0: forcing r0 to be precise\
+- force_precise: frame0: forcing r0 to be precise\
+- force_precise: frame0: forcing r0 to be precise\
+- force_precise: frame0: forcing r0 to be precise\
+- mark_precise: frame0: last_idx 6 first_idx 6\
++ mark_precise: frame0: last_idx 6 first_idx 4\
++ mark_precise: frame0: regs=r4 stack= before 6: (b7) r0 = -1\
++ mark_precise: frame0: regs=r4 stack= before 5: (79) r4 = *(u64 *)(r10 -8)\
++ mark_precise: frame0: regs= stack=-8 before 4: (7b) *(u64 *)(r3 -8) = r0\
++ mark_precise: frame0: parent state regs=r0 stack=:\
++ mark_precise: frame0: last_idx 3 first_idx 3\
++ mark_precise: frame0: regs=r0 stack= before 3: (55) if r3 != 0x7b goto pc+0\
++ mark_precise: frame0: regs=r0 stack= before 2: (bf) r3 = r10\
++ mark_precise: frame0: regs=r0 stack= before 1: (57) r0 &= 255\
++ mark_precise: frame0: parent state regs=r0 stack=:\
++ mark_precise: frame0: last_idx 0 first_idx 0\
++ mark_precise: frame0: regs=r0 stack= before 0: (85) call bpf_get_prandom_u32#7\
++ mark_precise: frame0: last_idx 7 first_idx 7\
+ mark_precise: frame0: parent state regs= stack=:",
+ .result = VERBOSE_ACCEPT,
+ .retval = -1,
+diff --git a/tools/testing/selftests/mount_setattr/mount_setattr_test.c b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
+index c6a8c732b80217..304e6422a1f1ce 100644
+--- a/tools/testing/selftests/mount_setattr/mount_setattr_test.c
++++ b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
+@@ -1026,7 +1026,7 @@ FIXTURE_SETUP(mount_setattr_idmapped)
+ "size=100000,mode=700"), 0);
+
+ ASSERT_EQ(mount("testing", "/mnt", "tmpfs", MS_NOATIME | MS_NODEV,
+- "size=100000,mode=700"), 0);
++ "size=2m,mode=700"), 0);
+
+ ASSERT_EQ(mkdir("/mnt/A", 0777), 0);
+
+diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
+index d65fdd407d73f9..1c0dd2f7816782 100755
+--- a/tools/testing/selftests/net/pmtu.sh
++++ b/tools/testing/selftests/net/pmtu.sh
+@@ -1961,7 +1961,7 @@ check_running() {
+ pid=${1}
+ cmd=${2}
+
+- [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "{cmd}" ]
++ [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "${cmd}" ]
+ }
+
+ test_cleanup_vxlanX_exception() {
+diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c
+index 0f6cca61ec94ba..a85ae8148db84e 100644
+--- a/tools/testing/selftests/resctrl/fill_buf.c
++++ b/tools/testing/selftests/resctrl/fill_buf.c
+@@ -51,29 +51,6 @@ static void mem_flush(unsigned char *buf, size_t buf_size)
+ sb();
+ }
+
+-static void *malloc_and_init_memory(size_t buf_size)
+-{
+- void *p = NULL;
+- uint64_t *p64;
+- size_t s64;
+- int ret;
+-
+- ret = posix_memalign(&p, PAGE_SIZE, buf_size);
+- if (ret < 0)
+- return NULL;
+-
+- p64 = (uint64_t *)p;
+- s64 = buf_size / sizeof(uint64_t);
+-
+- while (s64 > 0) {
+- *p64 = (uint64_t)rand();
+- p64 += (CL_SIZE / sizeof(uint64_t));
+- s64 -= (CL_SIZE / sizeof(uint64_t));
+- }
+-
+- return p;
+-}
+-
+ static int fill_one_span_read(unsigned char *buf, size_t buf_size)
+ {
+ unsigned char *end_ptr = buf + buf_size;
+@@ -135,41 +112,48 @@ static int fill_cache_write(unsigned char *buf, size_t buf_size, bool once)
+ return 0;
+ }
+
+-static int fill_cache(size_t buf_size, int memflush, int op, bool once)
++static unsigned char *alloc_buffer(size_t buf_size, int memflush)
+ {
+- unsigned char *buf;
++ void *buf = NULL;
++ uint64_t *p64;
++ ssize_t s64;
+ int ret;
+
+- buf = malloc_and_init_memory(buf_size);
+- if (!buf)
+- return -1;
+-
+- /* Flush the memory before using to avoid "cache hot pages" effect */
+- if (memflush)
+- mem_flush(buf, buf_size);
+-
+- if (op == 0)
+- ret = fill_cache_read(buf, buf_size, once);
+- else
+- ret = fill_cache_write(buf, buf_size, once);
++ ret = posix_memalign(&buf, PAGE_SIZE, buf_size);
++ if (ret < 0)
++ return NULL;
+
+- free(buf);
++ /* Initialize the buffer */
++ p64 = buf;
++ s64 = buf_size / sizeof(uint64_t);
+
+- if (ret) {
+- printf("\n Error in fill cache read/write...\n");
+- return -1;
++ while (s64 > 0) {
++ *p64 = (uint64_t)rand();
++ p64 += (CL_SIZE / sizeof(uint64_t));
++ s64 -= (CL_SIZE / sizeof(uint64_t));
+ }
+
++ /* Flush the memory before using to avoid "cache hot pages" effect */
++ if (memflush)
++ mem_flush(buf, buf_size);
+
+- return 0;
++ return buf;
+ }
+
+-int run_fill_buf(size_t span, int memflush, int op, bool once)
++int run_fill_buf(size_t buf_size, int memflush, int op, bool once)
+ {
+- size_t cache_size = span;
++ unsigned char *buf;
+ int ret;
+
+- ret = fill_cache(cache_size, memflush, op, once);
++ buf = alloc_buffer(buf_size, memflush);
++ if (!buf)
++ return -1;
++
++ if (op == 0)
++ ret = fill_cache_read(buf, buf_size, once);
++ else
++ ret = fill_cache_write(buf, buf_size, once);
++ free(buf);
+ if (ret) {
+ printf("\n Error in fill cache\n");
+ return -1;
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index dd3546655657a9..a848e9c755787c 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -91,7 +91,7 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
+ char *resctrl_val);
+ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
+ int group_fd, unsigned long flags);
+-int run_fill_buf(size_t span, int memflush, int op, bool once);
++int run_fill_buf(size_t buf_size, int memflush, int op, bool once);
+ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param);
+ int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd);
+ void tests_cleanup(void);
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index 45439e726e79c5..d77fdf356e98eb 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -102,13 +102,12 @@ void get_event_and_umask(char *cas_count_cfg, int count, bool op)
+ char *token[MAX_TOKENS];
+ int i = 0;
+
+- strcat(cas_count_cfg, ",");
+ token[0] = strtok(cas_count_cfg, "=,");
+
+ for (i = 1; i < MAX_TOKENS; i++)
+ token[i] = strtok(NULL, "=,");
+
+- for (i = 0; i < MAX_TOKENS; i++) {
++ for (i = 0; i < MAX_TOKENS - 1; i++) {
+ if (!token[i])
+ break;
+ if (strcmp(token[i], "event") == 0) {
+diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
+index 7dd5668ea8a6e3..28f35620c49919 100644
+--- a/tools/testing/selftests/vDSO/parse_vdso.c
++++ b/tools/testing/selftests/vDSO/parse_vdso.c
+@@ -222,8 +222,7 @@ void *vdso_sym(const char *version, const char *name)
+ ELF(Sym) *sym = &vdso_info.symtab[chain];
+
+ /* Check for a defined global or weak function w/ right name. */
+- if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC &&
+- ELF64_ST_TYPE(sym->st_info) != STT_NOTYPE)
++ if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
+ continue;
+ if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
+ ELF64_ST_BIND(sym->st_info) != STB_WEAK)
+diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c
+index bc71cbca0dde70..a1f506ba557864 100644
+--- a/tools/testing/selftests/watchdog/watchdog-test.c
++++ b/tools/testing/selftests/watchdog/watchdog-test.c
+@@ -334,7 +334,13 @@ int main(int argc, char *argv[])
+
+ printf("Watchdog Ticking Away!\n");
+
++ /*
++ * Register the signals
++ */
+ signal(SIGINT, term);
++ signal(SIGTERM, term);
++ signal(SIGKILL, term);
++ signal(SIGQUIT, term);
+
+ while (1) {
+ keep_alive();
+diff --git a/tools/testing/selftests/wireguard/netns.sh b/tools/testing/selftests/wireguard/netns.sh
+index 405ff262ca93d4..55500f901fbc36 100755
+--- a/tools/testing/selftests/wireguard/netns.sh
++++ b/tools/testing/selftests/wireguard/netns.sh
+@@ -332,6 +332,7 @@ waitiface $netns1 vethc
+ waitiface $netns2 veths
+
+ n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
++[[ -e /proc/sys/net/netfilter/nf_conntrack_udp_timeout ]] || modprobe nf_conntrack
+ n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout'
+ n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream'
+ n0 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j SNAT --to 10.0.0.1